Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];

Вниз

копирование оъектов   Найти похожие ветки 

 
Rel_   (2003-08-18 09:10) [0]

Мастера, отсоветуйте, как самым простым способом сделать след:

есть родительский класс, например "TА", есть несколько дочерних классов, например TB1 = class (TA), TВ2 ...

есть объект L : TList, содержащий указатели на некоторый набор оъектов классов TB1, TB2 ...

Указатели могут создаваться произвольным образом, например,

var c1 : TA;
...

c1 := TB1.Create();
L.Add(c1);
c1 := TB2.Create();
L.Add(c1);
...
c2 := TBn.Create();
L.Add(c1);

т.е. классический виртуальный механизм. Получается список указателей на дочерние объекты.

Как мне откопировать часть объектов в другой список, например с 5-го по 10-ый в объект L2 : TList.

Причём, копироваться должны не указатели (это просто). Должны создаваться объекты полностью аналогичные копируемым объектам и указатели на них заноситься в новый список L2. Копируемые оъекты также должны быть виртуально наследованы от родительского.

Заранее огромное спасибо за участие. Всё, что неясно изложил, проясню.


 
Skier   (2003-08-18 09:15) [1]

1) для копирования существует метод TPersistent.Assign(...)
Тебе нужно его перекрыть в своих классах...
2) для создания объектов (как вариант) можно использовать
метакласс и методы RegisterClass(es), GetClass(...), FindClass(...)


 
Rel_   (2003-08-18 09:19) [2]

to Skier ©

Проясните мне пожалуйста. Не въезжаю пока, особенно 2-ой пункт.


 
Skier   (2003-08-18 09:26) [3]

2)
- TАClass = class of TА; //метакласс
- RegisterClasses([TA, TB1, TB2...]) //регистрация классов
//можно поставить RegisterClasses в секцию initialization
- GetClass("Reqiured_Class_Name").Create(...); //создание
экземпряра класса Reqiured_Class_Name

Но всё ещё зависит от того от какого класса наследуется TA
(вариант с GetClass подойдёт если TA = class(TComponent), или у
TA виртуальный конструктор)


 
Skier   (2003-08-18 09:29) [4]

ошибочка - TАClass(GetClass("Reqiured_Class_Name")).Create(...);


 
Rel_   (2003-08-18 09:36) [5]

to Skier ©

я посмотрел -- TPersistent.Assign(...). Так энто просто копирует свойства из одного оъекта в другой и можно перегрузить данный метод по своему усмотрению, но для этого сначала необходимо создать новый объект. А вот как его создать - не знаю. Ведь для меня энто всё просто указатели на объект родительского класса кTA, а что там скрывается TB1, TB2 ... - я не знаю. Т.е. Как я перед копированием определю, метод Create какого дочернего класса был вызван.


 
Skier   (2003-08-18 09:41) [6]


> но для этого сначала необходимо создать новый объект. А
> вот как его создать - не знаю.

Книги !


 
Camus   (2003-08-18 09:53) [7]

1. Конструктор TA сделайте виртуальным.

2. Объявите после TA:
TAClass = class of TA;

3. Создание:
List2.[i] := TAClass(TA(List1[i]).ClassType).Create(...);

4. Копирование (TA должен быть потомком TPersistent, либо надо написать в нем свой Assign):
TA(List2[i]).Assign(TA(List1[i]));


 
Rel_   (2003-08-18 09:56) [8]

to Skier ©

Ну ладно шутить (или подскажи, какие книги есть с описанием работы с виртуальными классами). Как пользоваться конструктором я знаю. Я говорю лишь про то, что по указателю я не смогу определить, на какой объект он указывает. Т.е. не смогу определить конструктор какого дочернего класса вызывался при создании объекта, и, соответственно не определю, какой конструктор мне вызывать для нового (копируемого) объекта.

Если так будет понятнее, то для решения данной задачи в Builder я бы попробовал создать виртуальный конструктор копирования в родительском классе и перезаписать (override для уточнения) его во всех дочерних классах.

PS : А у тебя раньше ник был не Sky3D ???


 
Skier   (2003-08-18 10:02) [9]

Rel_ (18.08.03 09:56) [8]
> Я говорю лишь про то, что по указателю я не смогу определить,
> на какой объект он указывает. Т.е. не смогу определить конструктор
> какого дочернего класса вызывался при создании объекта,
> и, соответственно не определю, какой конструктор мне вызывать
> для нового (копируемого) объекта.

Всё можно разрулить при желании
1) все указатели в твоём в списке это всё равно ведь объекты,т.е.
смело можно написать такое приведение
типа TObject(PointerVar)
А лучше бы вообще использовать TObjectList.
2) Можно получить и имя класса TObject(PointerVar).ClassName
3) А дальше я уже примерно написал как действовать...


> А у тебя раньше ник был не Sky3D ???

Нет.


 
Rel_   (2003-08-18 10:23) [10]

Спасибо, щас попробую.


 
Camus   (2003-08-18 10:57) [11]

> Rel_ (18.08.03 09:56) [8]
> по указателю я не смогу определить, на какой объект он
> указывает

See:
Camus © (18.08.03 09:53) [7]


 
Rel_   (2003-08-18 12:06) [12]

to Camus ©

Что-то я не понял след: 2 пункта:

2. Объявите после TA:
TAClass = class of TA; ??? что это за синтаксис

3. Создание:
List2.[i] := TAClass(TA(List1[i]).ClassType).Create(...);

Я проясню, как я понял, а вы поправьте, если не так.

TA = class ; //родительский класс
constructor Create(...); virtual; //что-то в этом роде.
end;

TB1 = class(TA) ; //родительский класс
constructor Create(...); override;
end;

TB2 = class(TA) ; //родительский класс
constructor Create(...); virtual;
end;

далее пусть уже имеется некий L1: TList, заполненный дочерними
объектами (вернее указателями на них).

А вот так я копирую (т.е. создаю новый объект по образу и подобию и копирую)некий i-ый элемент в L2 :TList.

L2.Add((TA(L[i]).ClassType).Create(...)); // вот этот момент я что-то не понял. Запутался с твоими TAClass и TA - что это за классы???


 
Camus   (2003-08-18 13:44) [13]

type
TA = class( TPersistent) // Чтобы был Assign
public
constructor Create(...); virtual;
end;

TAClass = class of TA; // Объявление метакласса

TB1 = class(TA);
public
constructor Create(...); override;
end;

TB2 = class(TA);
public
constructor Create(...); override;
end;

// Создаем и сразу копируем:
TA(L2[L2.Add(TAClass(TA(L[i]).ClassType).Create(...))]).Assign(TA(L[i] ));

Здесь:
TA(L[i]) - приводит указатель L[i] к TA
TA(L[i]).ClassType - дает РЕАЛЬНЫЙ класс объекта L[i]
TAClass(...) - приводит этот класс к TAClass
TAClass(...).Create(...) - создает объект того же класса, что и
объект, который РЕАЛЬНО сидит в L[i] (т.к. он виртуальный)
L2.Add(...) - добавляет созданный объекта в L2 и дает его индекс
L2[этот_индекс] - дает указатель на этот объект
TA(L2[этот_индекс]) - приводит этот указатель к TA
TA(L2[этот_индекс]).Assign(TA(L[i])) - вызывает Assign именно
того клвсса, который реально был создан (т.к. Assign тоже
виртуальный)

Пример реализации метода Assign (его надо перекрыть во всех классах, котрые должны уметь копироваться):

procedure Tx.Assign(Source: TPersistent); // где x = A | B1 | B2
begin
if Source is Tx then
with Tx(Source) do
begin
... // Копируем все, что нужно ТОЛЬКО в данном классе Tx
end
else inherited
end;


 
Camus   (2003-08-18 13:47) [14]

(т.к. он "виртуальный")

"Он" - это конструктор, конечно.


 
pasha_golub   (2003-08-18 14:25) [15]

2Camus

Классно :-)


 
Rel_   (2003-08-18 14:55) [16]

to Camus ©
Поистине классно - и логично. СПАСИБО.

Кстати, вот что я накопал по энтому поводу в фиде (только на сях). Энто на тот случай, если я не хочу наследовать от TPersistent:

class A {
public:
A();
A(A const &);
virtual A* clone(){ return A(*this); }
...
};

class B : public A {
public:
B();
B(B const &);
B* clone(){ return B(*this); }
...
};

A* p =new B;
A* p2 =p->clone();

по моему тоже логично !!!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.012 c
1-1455
TolikM
2003-08-18 17:38
2003.09.01
SaveDialog для создания каталогов


6-1533
nester
2003-06-25 18:16
2003.09.01
как перехватить в IE 404 not found и подсунуть вместо этого свое


1-1381
Dimon
2003-08-16 19:27
2003.09.01
Синтаксис С++:(seen_eap |= PW_MESSAGE); Как это выгл. в Delphi??


14-1656
Васька
2003-08-12 17:04
2003.09.01
Изображения


14-1557
Best Guns
2003-08-10 23:10
2003.09.01
Безопасен ли The Bat! ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский