Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Конструктор класса в VB 6.0 - Есть предположения? Добавлено: 05.08.06 02:54  

Автор вопроса:  Dr. Zwoo4 | ICQ: 319248917 
Я уже вешаюсь. Реально. Народ! Кто - нибудь сталкивался с задачей (?):

Class clsMyData
   Private ID as Long        'например
   Public DATA_SET as String 'например
   Public или Private ещё чего - нибудь

   Public Sub'ы, Function'ы итд...
End Class

Dim myDataClassA as New clsMyData
'далее следуют какие-то операции по заполнению его переменных

Dim myDataClassB as clsMyData
'теперь задача перекинуть все данные из класса А в класс Б, например:
Set myDataClassB = myDataClassA

И всё бы замечательно, да вот только код
myDataClassB.DATA_SET = "Упс..."
заменит значение в обоих классах. Получается, что класс Б - это "ссылка" на клас А. Ладно. Попытаемся её разорвать.

Sub CopyClassData(ByRef cDest as clsMyData,ByRef cSrc as clsMyData)
   Dim myDataClassBUFF as clsMyData
   Set myDataClassBUFF = cSrc
   Set cDest = myDataClassBUFF
   Set myDataClassBUFF = Nothing
End Sub
'...
CopyClassData myDataClassB, myDataClassA

Парадокс! Эффект тот же! Едем дальше.
Ссылка? Хорошо. По определению, юзердефайнд типы и объекты в VB можно передавать только по ссылке. Прикол:

Sub CopyClassData(ByRef cDest as clsMyData,ByVal cSrc as clsMyData)
   Set cDest = cSrc
   Set cSrc = Nothing
End Sub
'...
CopyClassData myDataClassB, myDataClassA

Забавно, не правда? Работает и даёт точно такой же результат. Почему? И как мне всё же решить эту задачу. Просто класс очень сложный и писать к нему "конструктор" не очень хочется.

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 Dr. Zwoo4



ICQ: 319248917 

Вопросов: 3
Ответов: 25
 Профиль | | #1 Добавлено: 05.08.06 03:20
Ну, да. Так - то действительно, я гонял из пустого в порожнее. Во всех случаях манипуляции производились с именоваными референсами на объект. ByVal и ByRef всего лишь запрещает/разрешает изменение самой ссылки, но никак не объекта.
Тем не менее, вопрос не закрыт. Каким образом можно создать копию объекта и ссылку на него?
Либо я не знаю какого - то заветного слова в языке VB, либо я чего - то недопонимаю.
Заранее "НО": Варианты с копированием через средства API не рассматриваются. Было бы просто скопировать участок памяти и всё! Здесь уже не практика, а скорее шкурный интерес.

Ответить

Номер ответа: 2
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #2 Добавлено: 05.08.06 03:23
Dim myDataClassA as New clsMyData
'далее следуют какие-то операции по заполнению его переменных

Dim myDataClassB as clsMyData
'теперь задача перекинуть все данные из класса А в класс Б, например:


А почему во-втором случае без New?

Ответить

Номер ответа: 3
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #3 Добавлено: 05.08.06 03:33
Каким образом можно создать копию объекта и ссылку на него?

В общем случае, разумеется, никак. В общем случае скопировать себя может только сам объект, для чего в нём может быть предусмотрен разработчиком метод Clone().

Если такового нет, можно создать новый объект и присвоить каждое значение свойства по отдельности. Обломившись на свойствах только для чтения, и на других приятных вещах, типа запомненного в private-переменной оригинала случайного числа.

Ответить

Номер ответа: 4
Автор ответа:
 Dr. Zwoo4



ICQ: 319248917 

Вопросов: 3
Ответов: 25
 Профиль | | #4 Добавлено: 05.08.06 04:40
2HACKER: А зачем это делать дважды? Инициализация так или иначе произойдёт, но позже, при манипуляциях с объектом.

2GSerg: Очень сильно этого боялся. Надеялся, что всё же есть какое - то магическое слово. Действительно, похоже что Бэйсиковские классы предопределёнными конструкторами обделили. Жаль.

Тогда другой вопрос: для того, чтобы скопировать участок памяти, нужно знать размеры копируемой области. Соответственно встаёт вопрос, а как определить размер класса данных, при условии, что в нём есть динамически изменяющиеся строки?

Для всех примитивных типов и UDT есть всё та же фишка Len(<extension> as Any) as Long. Для объектных переменных она не катит. Вообще, реально это? По сути, объектная переменная это не совсем переменная. Скорее кусок программы...

Ответить

Номер ответа: 5
Автор ответа:
 Viper



ICQ: 249094859 

Вопросов: 0
Ответов: 310
 Профиль | | #5 Добавлено: 05.08.06 08:30
Ежели класс не содержит внутри себя ссылочных переменных, то его содержимое можно скопировать из одного класса в другой при помощи CopyMemory, недокументированных функций типа VarPtr и ObjPtr и вручную подсчитанного размера данных. Но все это откровенное стучание в бубен. А если внутри есть ссылки (те же строки), то проблема усложнятся в разы.

Ответить

Номер ответа: 6
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #6 Добавлено: 05.08.06 14:44
Действительно, похоже что Бэйсиковские классы предопределёнными конструкторами обделили. Жаль.

Приведи пример, когда такого обделения нет.

и вручную подсчитанного размера данных.

Вот здесь поподробнее, пожалуйста.
Как будем считать?

Ответить

Номер ответа: 7
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #7 Добавлено: 05.08.06 16:58
Если такового нет, можно создать новый объект и присвоить каждое значение свойства по отдельности.
Это я и имел ввиду во втором посте. Про облом тоже факт.

Придётся писать конструктор...

Ответить

Номер ответа: 8
Автор ответа:
 Dr. Zwoo4



ICQ: 319248917 

Вопросов: 3
Ответов: 25
 Профиль | | #8 Добавлено: 05.08.06 17:51
Короче говоря, после определённых операций типа "уга - джага", и рысканий по иннету выяснилось, что объектные переменные нельзя Put, Get в Random файлах, нельзя взвешивать (Len() всех переменных внутри объекта) и нельзя CopyMemory в т.ч. через указатели. Видимо, помимо данных (даже в классе, в котором всего одна переменная и та типа Long) содержатся ещё какие - то данные и в общем виде он представляется как код+данные (читай кусок программы). Следовательно, все конструкции, применительные для UDT классам просто недоступны. Складывается впечатление, что это сделано нарошно, как защита от дурака.
Вывод: если вы делаете сложный класс данных, с приватными переменными, уникальными идентификаторами и прочими прелестями - в первую очередь, позаботьтесь о функции GetClone() as клсИмяКласса - иначе, на какой - нибудь стадии разработки будет ой... А так же функции CopyPrivateData() и подобные. Короче, маразм полный.

Ответить

Номер ответа: 9
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #9 Добавлено: 05.08.06 22:53
Короче, маразм полный.

Годика через три, набив шишечек и набравшись опыта, вернись к этому вопросу. Если стукнешь себя по лбу и скажешь "Блин, вот дурак был, не понимал, насколько здесь всё красиво и правильно сделано" - значит всё ок. Если нет - значит, ещё через три годика операцию повторить...

Ответить

Номер ответа: 10
Автор ответа:
 Dr. Zwoo4



ICQ: 319248917 

Вопросов: 3
Ответов: 25
 Профиль | | #10 Добавлено: 06.08.06 03:29
2GSerg: Верно подмечено, но, думаю, что к этому времени VB6.0 будет просто неактуален (собственно, он уже неактуален, по заверениям мелкомягких - есть замечательная весч .NET)

А вообще, классы данных в первую очередь предполагается использовать при работе с СУБД, а там есть всё необходимое для копирования, записи итд. Уже стучать себе по лбу? Наверное, не стану. Потому что задача была не научиться копировать, сохранять и тд, а просто понять, есть ли "магический" конструктор в VB или нет.

Ответить

Номер ответа: 11
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #11 Добавлено: 07.08.06 10:33
На деле, если поддерживается интерфейс IPersist - проблем быть не должно. В противном случае лучше бросить это дело сразу. При всем желании, даже если скопировать все Public члены класса - результат скорее всего не будет ожидаемым. Приватные члены и ссылочные переменные портят всю малину :)
ЗЫ Опять таки, если определен конструктор копирования - ситуация меняется. Для VB, к сожалению, это можно сделать только методом класса.

Ответить

Номер ответа: 12
Автор ответа:
 Dr. Zwoo4



ICQ: 319248917 

Вопросов: 3
Ответов: 25
 Профиль | | #12 Добавлено: 07.08.06 23:29
Да, для самописных классов такой приём очевиден. А как насчёт классов, предоставляемых, к примеру, каким - нибудь COM?

Ответить

Номер ответа: 13
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #13 Добавлено: 08.08.06 11:14
Конструктор копирования может присутствовать не только в самописном классе ;) Так же как и поддержка IPersist.
ЗЫ "каким - нибудь COM" - жжош, .NETчик :))

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам