Назначение объектов в VB6

Я пытаюсь создать два идентичных объекта в VB6 с помощью операторов присваивания; что-то вроде этого…

Dim myobj1 As Class1 Dim myobj2 As Class1 Set myobj1 = New Class1 myobj1.myval = 1 Set myobj2 = myobj1 

Стало очевидным, что это не создает два объекта, а скорее две ссылки на один и тот же объект, и это не то, что мне нужно. Есть ли способ создать второй объект таким образом, или мне нужно скопировать объект по одному члену за раз …

 Set myobj2 = new Class1 myobj2.mem1 = myobj1.mem1 ... 

?

Редактировать 2 Скотт Уитлок обновил свой отличный ответ, и я включил его изменения в этот теперь действующий fragment кода.

 Private Type MyMemento Value1 As Integer Value2 As String End Type Private Memento As MyMemento Public Property Let myval(ByVal newval As Integer) Memento.Value1 = newval End Property Public Property Get myval() As Integer myval = Memento.Value1 End Property Friend Property Let SetMemento(new_memento As MyMemento) Memento = new_memento End Property Public Function Copy() As Class1 Dim Result As Class1 Set Result = New Class1 Result.SetMemento = Memento Set Copy = Result End Function 

Затем выполняется выполнение задания в коде …

 Set mysecondobj = myfirstobj.Copy 

Как и многие современные языки, VB6 имеет типы значений и ссылочные типы. Классы определяют ссылочные типы. С другой стороны, ваши основные типы, такие как Integer являются типами значений.

Основное различие заключается в назначении:

 Dim a as Integer Dim b as Integer a = 2 b = a a = 1 

Результатом является то, что a равно 1, а b равно 2. Это связано с тем, что присвоение типов значений создает копию. Это потому, что каждая переменная имеет пространство, выделенное для значения в стеке (в случае VB6 Integer занимает 2 байта в стеке).

Для classов он работает по-разному:

 Dim a as MyClass Dim b as MyClass Set a = New MyClass a.Value1 = 2 Set b = a a.Value1 = 1 

В результате, как a.Value1 и b.Value1 равны 1. Это связано с тем, что состояние объекта хранится в куче, а не в стеке. В стеке хранится только ссылка на объект, поэтому Set b = a перезаписывает ссылку. Интересно, что VB6 явно говорит об этом, заставляя вас использовать ключевое слово Set . Большинство других современных языков не требуют этого.

Теперь вы можете создавать свои собственные типы значений (в VB6 они называются User Defined Types, но на большинстве других языков они называются структурами или структурами). Вот учебник .

Различия между classом и определенным пользователем типом (кроме classа, являющегося ссылочным типом и UDT, являющегося типом значения) состоит в том, что class может содержать поведение (методы и свойства), где UDT не может. Если вы просто ищете class типа записи, то UDT может быть вашим решением.

Вы можете использовать сочетание этих методов. Предположим, вам нужен class, потому что у вас есть определенные поведения и вычисления, которые вы хотите включить вместе с данными. Вы можете использовать шаблон памяти, чтобы удерживать состояние объекта внутри UDT:

 Type MyMemento Value1 As Integer Value2 As String End Type 

В своем classе убедитесь, что все ваше внутреннее состояние хранится внутри частного члена типа MyMemento . Напишите свои свойства и методы, чтобы они использовали данные только в одной переменной частного члена.

Теперь сделать копию вашего объекта просто. Просто напишите новый метод в своем classе под названием Copy() который возвращает новый экземпляр вашего classа и инициализирует его копией своего собственного воспоминания:

 Private Memento As MyMemento Friend Sub SetMemento(NewMemento As MyMemento) Memento = NewMemento End Sub Public Function Copy() as MyClass Dim Result as MyClass Set Result = new MyClass Call Result.SetMemento(Memento) Set Copy = Result End Function 

Friend только скрывает это от вещей вне вашего проекта, поэтому он не делает ничего, чтобы скрыть SetMemento , но это все, что вы можете сделать с VB6.

НТН

@Scott Whitlock, я не смог заставить ваш код работать, но если он сработает, было бы здорово.

Я создал регулярный модуль, где я помещаю тип памяти

 Type MyMemento Value1 As Integer Value2 As String End Type 

Затем я создаю модуль classа MyClass с кодом

 Private Memento As MyMemento Friend Sub SetMemento(NewMemento As MyMemento) Memento = NewMemento End Sub Public Function Copy() as MyClass Dim Result as MyClass Set Result = new MyClass Result.SetMemento(Memento) Set Copy = Result End Function 

Наконец, я пытаюсь вызвать функцию копирования в другом регулярном модуле, таком как

 Sub Pruebas() Dim Primero As MyClass, segundo As MyClass Set Primero = New MyClass Set segundo = New MyClass Set segundo = Primero.Copy End Sub 

Я получаю сообщение (под рисунком): Ошибка компиляции: El tipo de agumento de ByRef не совпадает

Вот изображение (не более 10 баллов, так вот ссылка): http://sofru.miximages.com/class/KPdBR.gif

Я не смог получить сообщение на английском языке, я живу в Испании.

Будете ли вы так любезны предоставить пример в VBA Excel ?, я действительно пытался сделать эту работу.

Спасибо за вашу работу

===============================================

EDIT: проблема решена:

Проблема была в строке «Result.SetMemento (Memento)», в VBA ей нужно было вызвать «Call»

 Public Function Copy() As MyClass Dim Result As MyClass Set Result = New MyClass Call Result.SetMemento(Memento) Set Copy = Result End Function 

Он отлично работает, благодаря Скотту Уитлоку, вы гений

или мне нужно скопировать объект по одному члену за раз …

К сожалению, да.

Возможно (но технически очень сложно) написать COM-сервер на C ++, который – с помощью интерфейса IDispatch – скопирует значение каждого свойства, но на самом деле это программирование на Высоком Храме , если бы мне пришлось это сделать, Я знаю, могу ли я это сделать, но я бы посмотрел на что-то вроде 10-дневной работы (и я знаю, как COM реализован на C ++, мне также нужно исследовать, есть ли в ATL-инфраструктуре что-нибудь, чтобы помочь и т.д.) ,

Я работал с Vb3, 4,5 и 6 для чего-то вроде 10 лет (на armх, 5 дней в неделю) и никогда не нашел хорошего способа сделать это, помимо ручного внедрения шаблонов сериализации, таких как Mementos и Save & Store, которые действительно просто вареные вплоть до фантастических способов копирования каждого участника, по одному за раз.

  • Скрыть двойную кавычку в строке VB
  • Что делает ключевое слово Call в VB6?
  • Обучение VB6
  • Как изменить расширенные свойства файла с помощью vba
  • Должен ли я использовать ключевое слово Call в VB / VBA?
  • Является ли VB6 IDE для Windows 7/8/10 64-бит?
  • Использовать stream в программировании в vb6
  • Каков наилучший вариант отображения текста Юникода (иврит и т. Д.) В VB6
  • Лучшая страtagsя перехода с VB6 на .NET
  • Отмена длительного процесса в VB6.0 без DoEvents?
  • Где я могу получить VB6 IDE
  • Interesting Posts

    Как выполнить qsort массив указателей на char в C?

    Синхронизация Google, Календарь и контакты Outlook

    Повторное использование весеннего контекста приложения в тестовых classах junit

    Фрагмент-fragmentация в Android

    Отключить кнопку сохранения в Adobe PDF Reader и скрыть панель меню в окне IE

    Как обеспечить, чтобы прокси создавались при использовании шаблона репозитория с каркасом сущности?

    Ошибка компиляции Xcode 7: «Ошибка команды из-за сигнала: Ошибка сегментации: 11″

    Как удалить и обновить запись в Hive

    Android находят местоположение GPS один раз, отображает диалоговое окно загрузки

    Использование заголовка диапазона HTTP с спецификатором диапазона, отличным от байтов?

    Windows / Создать txt-файлы вложенных папок с именами файлов в нем

    Моя клавиатура печатает сама по себе, может ли быть призрак?

    Правильная версия Fsharp.Core

    Как помочь Excel разобрать мой CSV автоматически

    Как определить, была ли перенаправлена ​​Console.In (stdin)?

    Давайте будем гением компьютера.