Вопросы по классам и типам.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Вопросы по классам и типам.

Сообщение AHTOXA » 10.03.2004 (Ср) 16:56

1)
Можно-ли в классах использовать типы, например в классе определена функция:

Public Function GetItem(ByVal idx as Integer, item as MenuItem) as integer
end Function

Тип MenuItem определен в другом модуле.

2)
Есть два класса C1 и C2, причем C2 является свойством C1

Sub Test
Dim c_one As C1
Dim c_two As C2
Set c_one = new C1
Set c_two = new C2
c_one.CTwo = c_two
/* теперь если изменим содержимое c_two, то изменится и содержимое c_one.CTwo, как этого избежать?
*/
End Sub

3)
Разрушится-ли класс при выходе из области видимости функции в предыдущем примере? Если нет, как сделать чтобы разрушался.
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.03.2004 (Чт) 10:21

Сишник, что ли... :)
  1. Можно. А буде нельзя, компилятор скажет :)
  2. А чего ты хочешь? Сам присвоил указатель на существующий объект, а потом удивляется. Ну нет в VB конструктора копирования.
  3. Все классы VB являются COM объектами и подчиняются COM reference count.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 11.03.2004 (Чт) 10:49

Ага, сишник ;)

1) Спрашиваю, потому что компилятор ругается:
"Only public user defined types defined in public object modules can be used as parametrs or return types for public procedures of class modules or as fields of public user defined types".
Хотя тип, который я использую как параметр, определен как public, в одном из модулей :(
2) Обидно, тем более что вот такой номер тоже не проходит:
Dim c_one, c_one1 As C1
c_one = new C1
c_one1 = new C1
c_one1.Copy(c_one) :(

Компилятор выдает сообщение: Объект не поддерживает данное свойство или метод, хотя функция существует (не нравиться ему параметр). Пришлось написать отдельную функцию копирования (вне класса) :(((((((
3) С COM работал, но очень давно и на C++. Там для освобождения объекта вызывался метод Release и вроде как при завершении программы, удалялся объект (если не был удален методом Release). Здесь то же самое?
4) Существует-ли в VB аналог "this"?
(чтобы провернуть что-то типа:
Public Function Destroy() As Integer
this = Nothing
Destroy = 1
End Function)
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.03.2004 (Чт) 11:12

  1. Заводим module, пихаем туда public тип, а все методы, которые этот тип юзают, делаем friend. Иначе бейсик считает, что мы хотим такие методы в публичное пользование предоставить, а для этого нужно заводить activex dll(exe) и описывать тип там.
  2. О тож :)
  3. addref, release и queryinterface в VB есть, в чём можно убедиться, написав оные слова (регистр поправит :)). Но юзать их не получится.
  4. Аналог есть, и называется Me. Но для уничтожения объекта в VB юзается set varObj=nothing, где varObj хранит указатель на объект. Перед этим, однако, очень пользительно обнулить все объектные ссылки, являющиеся членами уничтожаемого объекта, буде таковые имеются.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 11.03.2004 (Чт) 11:20

Вроде как что-то прояснилось. Спасибо за ответы :).
Bandit

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 11.03.2004 (Чт) 12:20

Я тут еще пару слов добавлю...

АНТОХА писал(а):Объект не поддерживает данное свойство или метод, хотя функция существует

VB не умеет понимать список переменных одного типа... В твоем объявлении Dim c1, c2 as Class1 только переменная с2 относится к классу Class1, а переменная с1 имеет тип Variant. Метод Copy, видимо, принимал в качестве параметра Class1, потому и ругался... Правильно было написать Dim c1 as Class1, c2 as Class1

Это первое. Теперь по поводу queryinterface. В VB6 по сравнению с предыдущими версиями есть довольно мощный механизм интерфейсов. Ищи по ключевому слову implements.
Если класс Class1 реализует 2 интерфейса Interface1 и Interface2, то в коде
Код: Выделить всё
Dim obj as Class1
Dim i as Interface1
set obj = new Class1
obj.SomeMethod
set i = obj
i.InterfaceMethod

строчка "set i = obj" фактически является вызовом QueryInterface.
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 11.03.2004 (Чт) 13:15

Насчет 1 - по барабану, что:
Dim c_one, c_two as C1 , что:
Dim c_one as C1
Dim c_two as C1

Мне кажется все равно как определять ибо:
c_one = new C1
c_two = new C1

Все равно при выхове Copy ругается (я так полагаю что в VB в функциях класса не может использоваться этот же класс как параметр)
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.03.2004 (Пт) 12:04

Даааа, злостный сишник :)

Всё можно и даже нужно. Дело в неправильном вызове.
В нашем любимом C (:)) вызов функции всегда осуществляется со скобками: myfunc(p1, p2);. Но в VB, вызывается метод (sub), то скобки юзать не нужно.
То есть, если у нас объявление в классе Class1
Код: Выделить всё
Public Sub CopyConstructor(ByVal another_instance As Class1)
  Me.value = another_instance.value
End Sub
, то вызов будет выглядеть как
Код: Выделить всё
  Dim c1 As New Class1
  Dim c2 As New Class1
 
  c2.value = 5
  c1.CopyConstructor c2
 
  MsgBox c1.value

Обрати внимание: спецификация byval случае с классами эквивалента сишной const.

Да, то же правило бесскобочного вызова применяется, когда вызывается функция, возвращаемое значение которой никуда не присваивается.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 12.03.2004 (Пт) 12:09

ЭЭЭ, я думал, что функции у которых 1 параметр должны вызываться со скобками :(
Bandit

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 14.03.2004 (Вс) 13:27

GSerg, меня кое-что в этой теме заинтересовало. Понятно, что писать я так никогда не буду, но интересен эффект - не понимаю, почему так происходит. Смотри:
в Class1
Код: Выделить всё
Public sub Copy(ByRef obj As Class1)
    Me.Value = obj.Value
end Sub

где-нибудь:
Код: Выделить всё
Dim c1 as Variant
Dim c2 as New Class1
Set c1 = New Class1
c1.Copy(c2)

Обрати внимание, что вызов как бы неправильный, со скобками. При этом компинятор это ЕСТ, не говоря ни слова (VB6, SP5). При вызове - ошибка "метод или пропертя не поддерживается".

Если вызов сделан правильно, те
с1.Copy c2
Call c1.Copy(c2)
то нормально - компилятор ругается, что передаю параметр по ссылке не того типа.
В чем дело?
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 14.03.2004 (Вс) 13:56

Господа, если вы общались с VB.NET, то знали бы такое понятие как СЕРИАЛИЗАЦИЯ ОБЪЕКТОВ.

В VB6 нужно создать пропертиБэГ и через него копировать объекты...
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.03.2004 (Вс) 17:49

Ты как спросишь, злостный сишник :wink: Так потом я не сплю долго, потому что фиг поймёшь!!! :twisted:

В общем, когда кофе уже закончился... Я эту ерунду скомпилировал в двух вариантах вызова... И дизассемблировал... Потом долго ковырялся... Так вот, в том блоке, который устанавливает в переменную указатель на объект, в правильном (бесскобочном) вызове присутствует команда mov esi, dword ptr [401020]. А в неправильном скобочном варианте этой команды нет, хотя всё остальное идентично. Так что в esi не оказывается нужного указателя на момент вызова __vbaObjSet.
Только не спрашивай почему, а?..
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 14.03.2004 (Вс) 18:12

Я не злостный сишник, я только учусь :) :oops:
Вопрос и правда чисто теоретический, прости, что отрываю от дел всякой глупостью...
А за исследования спасибо! Теперь я буду знать, что при вызове со скобочками не хватает "mov esi, dword ptr [...]". Спрашивать, почему, так и быть, не буду :wink:
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.03.2004 (Пн) 7:37

Ой! :)
Rainbow, прости пожалуйста :) Я просто не посмотрел, кто автор вопроса, и дефолтно предположил, что злостный сишник :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 17.03.2004 (Ср) 16:02

По вопросу к "c1.Copy(c2)"

Если бы вы обратили внимание или попробовали написать в VB эту строчку, то увидели бы ПРОБЕЛ между именем метода и параметром. Т.е. "c1.Copy (c2)". Если было бы ДВА параметра, то эквивалент был бы "c1.Copy (c2), (c2)". Такая вот петрушка.

Скобки вокруг параметра означают ВЫЧИСЛЕНИЕ выражения и использование полученного результата. Потому-то это обычная форма передачи по значению (ByVal) для параметров ByRef, если не желательно изменение.

Т.о. в случае (c2) VB пытается вычислить это выражение. А это делается через проперть со свойством id=Default.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 17.03.2004 (Ср) 16:38

Ого! Вот это интересно!

То есть если бы переменная в функции была, скажем строкой, то она передалась бы по значению (VB вычислил бы выражение, сложил результат в темповую переменную и передал бы в процедуру указатель на эту переменную).

Код: Выделить всё
Class1:
Public Sub Copy(s As String)
    s = "ha-ha!"
End Sub

Form:
Private Sub Form_Load()
Dim c1 As New Class1
Dim s As String
    s = "hello"
    c1.Copy (s)
    Debug.Print s 'hello
    c1.Copy s
    Debug.Print s 'ha-ha
End Sub


А в нашем случае VB просто не может вычислить (с2), тк не знает дефолтного свойства и ругается... Мдаа....
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 59

    TopList