Страница: 1 |
|
Вопрос: передача значений переменных двух классов
|
Добавлено: 27.08.07 16:03
|
|
Автор вопроса: KreAtoR
|
Сижу и думаю. Как перекинуть значения переменных одного класса в переменные другого класса.
Class1
private defaultVariablen
var1 as string
var2 as string
end type
class2
private defaultObject
var1 as string
var2 as string
end type
менятся при помощи Get и Let не охото (а если переменных будет не 2 а 100)
Решил создать Sub в котором все это будет действовать.
Пока что думаю реализовать это так.
1. переменные из класса1 и в классе1 перекинуть в massiv1(100) as variant
надо в данном случае, только один get (index as integer)
2. значения и massiv1 перекинуть в massiv2(100) класса2
при помощи одного Let
3. перекинуть в классе2 значения из massiv2(100) в переменные класса2.
Три шага, ну и должно все работать на ура.
вопрос в следующем.
Эта конструкция является грубой и неуклюжэй. Хотелось бы услышать предложения по оптимизации кода. или уже какие нить готовые соображения. Зачем ноты придумывать...
Ответить
|
Номер ответа: 3 Автор ответа: KreAtoR
Вопросов: 120 Ответов: 438
|
Профиль | | #3
|
Добавлено: 28.08.07 11:47
|
У меня есть класс из которого делается объект. У этого объекта есть мин три переменных
private Type defaultObject
Name as string
TechName as Object 'здесь кстати я
'и спрашивал про присвоение tech1=tech2
'в другой теме
Weight as Integer
End Type
private Object as defaultObject
Так же есть еще один класс (назовем его clsMain)который способен запоминать Properties других объектов из других классов. Так вот в тот момент когда clsMain взаимодействует с каким либо классом, точнее с объектом из класса, он берет всю необходимую информацию о объекте и сохраняет в своей памяти. Делает он это собственно два раза.
Первый раз когда встречается с объектом, идет сохранение в короткую память, объекта clsMain, в роцессе взаимодействия этих двух классов. clsMain может при необходимости загрузить себе в короткую память еще недостающей информации об объекте, а также может в процессе взаимодействия или сто пудов после взаимодействия, сохранить всю инфу об объекте в долгую память. После чего он при новом взаимодействии будет уже что то знать(помнить) о объетке. Но до сюда я еще не дошел, это я про долгую память. Я пока что короткую память делаю.
А вопрос собственно был о том, как легче и лучше достать все переменные одного объекта, одного класса и присвоить их переменным другого класса. В данном случае сюда:
private type defaultObject
Name as String
TechName as Object
Weight as Integer
end Type
private Type defaultBrain
Object as defaultObject
end Type
private Brain as defaultBrain
для меня проблема состоит в том, что это не массивы и я не могу их просто перебрать попорядочку, а делать присвоение для каждой переменной отдельно, тоже не хочется. Ведь у объекта Properties могут увеличиваться (кстати универсальный вариант былоб супер придумать) и если придется присваивать 100 или болле пересенных, а это значит что как минимум в одном классе должно быть 100 Property Get и в другом классе 100 Property Let!!!!!!!!!
А так как в VB6 это целая проблема и пиходится если честно писать два Саба для одной переменной Get и Let то это получается уже 400 Сабов. Ужас!!!!
Поэтому я и подумал как можно легче и универсально перекинуть переменные с одного места в другое.
пока делаю это так
В каком нить классе
private Type defaultObject
Name as string
TechName as Object 'здесь кстати я
'и спрашивал про присвоение tech1=tech2
'в другой теме
Weight as Integer
End Type
private Object as defaultObject
Public Property Get GetAllObjectProperties(index as integer)
dim varMas(100) as variant
with Object
varMas(0) = .Name
varMas(1) = .TechName
varMas(2) = .Weight
end With
GetAllObjectProperties = varMas(index)
End Properties
после чего в clsMain
делаю такое вот
private type defaultObject
Name as String
TechName as Object
Weight as Integer
end Type
private Type defaultBrain
Object as defaultObject
end Type
private Brain as defaultBrain
Public Sub LetAllObjectProperties(object as object)
dim varMas(100) as Variant
dim i as integer
for i=0 to 99 'почемуто не делается varMas.count-1
varMas(i) = object.GetAllObjectProperties(i)
with Brain.Object
.Name = varMas(0)
Set .TechName = varMas(1)
.Weight = varMas(2)
end Wtih
End Sub
после всего этого я вызываю гденить:
Public Form_Load()
LetAllObjectProperties ObjectNumber1
End Sub
Так вот да, так вот я могу, но хотелось бы сделать может лучше, может красивее. ведь как ни крути, а в одном и другом классе надо все равно присвоить каждой переменной ее занчение.
Спасибо за внимание )))))
P.S. я наверно все сказал ))))))))))
Ответить
|
Номер ответа: 5 Автор ответа: KreAtoR
Вопросов: 120 Ответов: 438
|
Профиль | | #5
|
Добавлено: 29.08.07 12:33
|
С добрым утром.
Давай упрощать. Насколько я понял, у тебя есть набор некоторых объектов. Судя по вставкам кода, эти объекты имеют какие-то общие для всех свойства и плюс каждый из них еще имеет какие-то свои свойства. Правильно?
Совершенно верно. есть набор объектов произведенных в данный момент и в данном примере из одного класса и у всех количество и порядок свойств одинаков. Тем примером, что я описал выше сохранение информации о объекте идет довольно таки просто. проблема возникнет, когда добавится еще один класс!!! и соответственно другие объекты, с другими свойствами.
Далее.. Общая цель твоих попыток сводится к тому, чтобы создать универсальное хранилище для любого из этих объектов. Правильно?
Если абстрактно говорить, то да. Создать так сказать мозг в котором хранится память о объекте при ранних взаимодействиях а также память о взаимодействии в данный момент времени.
И последний (пока что) вопрос: тебе обязательно хранить независимую копию выбранного объекта или можно ограничиться лишь ссылкой на оригинальный объект?
Я об этом тоже уже подумал. А стоит ли!!!! и пришел к выводу:
1. в момент взаимодействия не объект запоминает что я с ним делаю, а я это запоминаю, ведь мне это надо а не ему. Ему и так хорошо. У него вообще памяти нет.
2. после взаимодействия, я запоминаю какой был объект (при первой встрече, второй, а может и третей тоже), в то время как самому объекту совсем не интересно, каким он был 5 минут назад.
3. При взаимодействии с несколькими объектами память будет хранить уже несколько объектов, которые как Базе данных можно можно при надобности сравнить.
4. может конечно и не правильно, но для каждого объекта у меня есть два имени
Name as String
TechName as Object
Если пользователь воздействует на объект, то он обращается к Name as String в то время как в программном коде идет обращение к TechName as Object. Сначала хотел сделать Саб в котором выбиралось бы if name = "Wasja" then set TechName = main.object1 End if
но эта идея отпала, из за того что некоторые объекты имеют одинаковые Name as String. тоесть рассуждая далее нееобходимо еще несколько критериев сравнения. К примеру вес или рост. которые пользователь берет из памяти.
Представляю так:
Ага Вася. А какой Вася? А с третего подъезда и в зеленой рубашке?? да да знаю, TechName = Main.Wasja123
Если ты 4. пункт не понял что я имел ввиду, то просто не обращай на него внимание. это так еще просто догадки наверно.
После того, как ты ответишь на эти вопросы, я, возможно, попытаюсь войти в суть и предложить дельный совет.
надеюсь я ответил на твои вопросы и ты попытаешься войти в суть дела. )))))
Ответить
|
Номер ответа: 6 Автор ответа: el-paso
Вопросов: 0 Ответов: 56
|
Профиль | | #6
|
Добавлено: 29.08.07 14:10
|
Ну, потихоньку проясняется..
Совершенно верно. есть набор объектов произведенных в данный момент и в данном примере из одного класса и у всех количество и порядок свойств одинаков. Тем примером, что я описал выше сохранение информации о объекте идет довольно таки просто. проблема возникнет, когда добавится еще один класс!!! и соответственно другие объекты, с другими свойствами.
Значит, пока что имеется только один класс.. А нельзя ли его сделать более универсальным, чтобы не надо было писать другие классы? Например:
Class Universal (Universal.cls)
Public Name As String
Public TechName As String
Public Data [B]As Variant[/B]
И таким образом в Data запихивать любые данные об объекте.. (Кстати, какая причина вынудила объявлять переменную TechName как Object?)
Если абстрактно говорить, то да. Создать так сказать мозг в котором хранится память о объекте при ранних взаимодействиях а также память о взаимодействии в данный момент времени.
Т.е. есть набор объектов, отражающий текущее состояние чего-то глобального. Пользователь периодически изменяет какой-то из этих объектов, но старое состояние этого объекта требуется сохранить?
Если да, то тебе нужна процедура копирования объекта, что, кстати, при универсальном классе становится весьма простым:
Function CopyObject(obj As Universal) As Universal
Dim obj2 As New Universal
obj2.Name = obj.Name
obj2.TechName = obj.TechName
obj2.Data = obj.Data
Set CopyObject = obj2
End Function
Единственное ограничение, что переменная Data не может иметь ссылочный тип (т.е. тип Object или любого другого класса). Но, как я понял из ранних примеров, она таковой и не будет являться.
-------------------------------------------------
Мое решение (как я себе представляю суть):
1.
Объекты, отражающие текущее состояние, хранятся в коллекции (про Collection, надеюсь, не надо рассказывать?) - каждый объект под своим уникальным ключом (значение TechName). Пусть к примеру он будет глобально объявлен так:
Dim GlobalObjects As New Collection
2.
Объекты, с которыми пользователь уже взаимодействовал, тоже загоняются в коллекцию:
Dim SavedObjects As New Collection
3.
Каждый контрол, из тех, которые активируют объекты, имеет в свойстве Teg соответствующее значение TechName. (Как я помню, речь шла о Label'ах.)
Причем это должен быть массив контролов (Label(0), Label(1) и т.д.), т.к. надо будет написать всего один обработчик, похожий на следующий:
Private Sub Label_Click(Index As Integer)
'
' определяем новый текущий объект
Set ActiveObject = GlobalObjects(Label(Index).Tag)
'
' поскольку сейчас будем его изменять, то
' сохраним перед этим его нынешнюю версию
SavedObjects.Add CopyObject(ActiveObject)
'
End Sub
Однако, замечу, что этот вариант также можно реализовать и с помощью массивов, а не коллекций.
Я думаю, этого достаточно, чтобы мое понимание сути стало более ясным. И достаточно, чтобы натолкнуть автора на мысли о том, что делать дальше.
Кстати, этот пост содержит и ответ на вопрос о тэге, заданный где-то там, позже...
Ответить
|
Номер ответа: 8 Автор ответа: KreAtoR
Вопросов: 120 Ответов: 438
|
Профиль | | #8
|
Добавлено: 29.08.07 15:40
|
Значит, пока что имеется только один класс.. А нельзя ли его сделать более универсальным, чтобы не надо было писать другие классы? Например:
в принципе можно, но другие классы создаются по тому, что объекты имеют совершенно другую структуру. Если я смогу то сделаю по возможности только один класс. Хотя пока еще не знаю смогу.
Кстати, какая причина вынудила объявлять переменную TechName как Object
когда пользователь видит на экране название объекта, то в программном коде прописывается глоб. переменная ActiveObject as Object
и когда пользователь нажимает на Label вызывается функция, к примеру GetAllMethodsFromObject ActiveObject
Public Sub GetAllMethodsFromObject(Object as Object)
with object
main.text1.text = .getname
main.text2.text = .getChannel
end with
end sub
просто чтоб программа могла легко и просто обратится к любому объекту.
про Collection, надеюсь, не надо рассказывать?)
к сожалению надо, но идея мне очень понравилась )))))
Пасибо щас подумаем, как можно оптимизировать
2LamerOnLine
а немного подробней ты можешь сказать как это можно реализовать?
Ответить
|
Номер ответа: 9 Автор ответа: el-paso
Вопросов: 0 Ответов: 56
|
Профиль | | #9
|
Добавлено: 29.08.07 16:41
|
Идея коллекций очень проста. Это такой встроенный в VB класс, который позволяет хранить кучу объектов вместе и обращаться к ним не только по индексу (как в массивах), но и по ключу (какая-нибудь текстовая строка, к примеру).
Иллюстрированный пример:
' новая коллекция
Dim col As New Collection
' объект для вставки в коллекцию
Dim var1 As New ClassName
' инициализация объекта
var1.Property1 = "Value1"
var1.Property2 = "Value2"
...
' вставка объекта в коллекцию с ключом "MyKey"
col.Add var1, "MyKey"
' вставлять можно не только объекты но и примитивные переменные (строки, числа и т.д.):
Dim s1 As String: s1 = "Йа строчко"
col.Add s1, "MyString"
' особенность: ключи не могут повторяться!
col.Add something, "MyKey" ' ошибка!
' доступ к содержимому коллекции
Debug. Print col("MyKey" .Property1 ' -> "Value1"
Debug. Print col("MyString" ' -> "Йа строчко"
Debug. Print col(2) ' -> "Йа строчко"
' как видим индексация в коллекции - не с нуля, а с единицы!
' если извлекаем из коллекции ссылочную переменную, то не забываем про Set
Dim obj As ClassName
Set obj = col("MyKey"
' количество элементов в коллекции
Debug. Print col.Count
' удаление элемента
col.Remove "MyKey" ' или col.Remove 1 - в данном примере это одно и то же
' упрощенный перебор всех элементов коллекции в цикле
Dim v
Foreach v in col
Debug. Print v ' v - текущий элемент коллекции
Next v
' общепринятый прием очистки коллекции
Do While col.Count > 0: col.Remove 1: Loop
' удаление коллекции
Set col = Nothing
А вообще советую почитать об этом в умных книжках.
Ответить
|
Номер ответа: 10 Автор ответа: KreAtoR
Вопросов: 120 Ответов: 438
|
Профиль | | #10
|
Добавлено: 30.08.07 11:50
|
да да очень интересно, щас пойщу почитаю.
Задам сразу вопрос, так как ты знаешь можно ли его реализовать в Коллекции.
Каждый объект у меня имеет три состояния.
1. когда он просто есть, без моего участия
(у него какие то методы включены какие то нет)
2. когда он есть с моим участием, если я выбрал этот объект что хочу с ним работать
(тогда количество методов остается темже, но некоторые становятся False а другие соответственно True )
3. Когда я с этим объектом поработал и выбросил, не путать с тем что я отложил его в сторону(пункт 1), а уничтожил так сказать, тоесть все методы становятся False а через некоторое время они становятся автоматически снова на 1, так как объект может снова пригодиться.
Я думаю о том, чтоб прописать все три стадии а в процессе работы просто выбирать мне нужный
Как думаешь можно такое в Коллекции реализовать???
Ответить
|
Страница: 1 |
Поиск по форуму