Страница: 1 |
Страница: 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
И всё бы замечательно, да вот только код
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 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чик )