Есть такое понятие в С++ как виртуальные конструкторы. Я щас как раз читаю эту тему и пытаюсь понять, что это такое, но увы как то мне щас это тяжко дается. Хз чо так. Да и вообще виртуальный деструктор я тоже не знаю что это такое, но давайте хотя бы щас разберемся с виртуальными конструкторами.
На само деле виртуальных конструкторов не может быть, но обеспечить искомый эффект можно. Для инициализации (создания) объекта конструктор должен точно знать его тип, поэтому виртуальных конструкторов не бывает.
Я конечно строчки выше не полностью понял их смыл. Это я их так для массовки добавил. Ладно давайте посмотрим примерчик:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
//virtyal6nue konctryktoru #include <iostream> using std::cout; using std::endl; class Expr { public: int valE; //konctryktor po ymolchaniyu Expr():valE(0){} //konctryktor preobrazovani9 Expr(int a):valE(a){} //konctryktor kopii Expr(Expr& a):valE(a.valE){} //cozdaet novue ob6ektu virtual Expr* new_expr(){return new Expr();} //cozdanie kopii ob6ekta virtual Expr* clone(){return new Expr(*this);} }; class Cond : public Expr { public: int valC; //konctryktor po ymolchaniyu Cond():valC(0){} //konctryktor preobrazovani9 Cond(int a):valC(a){} //konctryktor kopii Cond(Cond& a):valC(a.valC){} //cozdanie novogo ob6ekta virtual Cond* new_expr(){return new Cond();} //vuzov k.po ymolchaniyu //cozdanie kopii ob6ekta virtual Cond* clone(){return new Cond(*this);} //vuzov k.preobraovani9 }; int main() { // 1. proverka procto na cozdanie kopii i novogo ob6ekta Expr e(8); Expr* p=e.new_expr(); cout <<"p->valE= "<<p->valE<<endl;//0 potomy chto novui ob6ekt p=e.clone(); cout <<"p->valE= "<<p->valE<<endl;//8 potomy chto klon // 2. proverka na cozdanie polimorfnogo ob6ekta Cond ce(9); cout <<"ce.valC= "<<ce.valC<<endl;//9 p=&ce; Expr* cePtr=p->new_expr(); //cozdaem novui ob6ekt Cond* prov=dynamic_cast<Cond*>(cePtr);//preobrazovuvaem v Cond* if(prov==0) cout <<"prov raven 0"<<endl; else cout <<"ycpewno preobrazovali iz Expr v Cond"<<endl; cout <<"prov->valC= "<<prov->valC<<endl;// vidim 0 potomy chto novui cozdalc9 ob6ekt cePtr=p->clone();//cozdat6 kopiyu ob6ekta prov=dynamic_cast<Cond*>(cePtr);//preobrazovuvaem if(prov==0) cout <<"prov raven 0"<<endl; else cout <<"ycpewno preobrazovali iz Expr v Cond"<<endl; cout <<"prov->valC= "<<prov->valC<<endl; //kak vidim ycpewnoe cozdanie kopii ob6ekta return 0; } |
В этом примерчике имеется два класса один базовый один производный от него Expr и Cond соответственно. Ну и две функции в каждом классе одна создает новый объект new_expr(), а вторая создает копию объекта clone(). Ну от и как мы видим функции эти нормально работают. При первом случае просто для вызова класса мы видим все нормально создается как копия объекта, так и просто новый объект.
Теперь разберем второй случай, что же там происходит? Ну мы видим, что при вызове создается указатель на Exptr* полиморфно, то есть если мы вызываем функцию clone() из указателя на базовый класс, которому присвоен указатель на производный класс или адрес производного объекта, то у нас просто вызывается функция правильно полиморфно объекта производного класса, но тип указателя Expr* так и остается, нам просто нужно его преобразовать с помощью оператора dynamic_cast<>() в тот объект который там создан мы его преобразовали в Cond* и оно преобразовалось потому, что он на самом деле и есть Cond* если б он был другого типа, то dynamic_cast<>() вернула бы 0 и все, но в нашем случае этого не произошло, значит делаем выводы правильно создан объект типа Cond все таки да и по выводу видно, что это Cond после перевода, потому, что есть данные клонированные из Cond.
Я наверно больше ничего добавлять не буду, думаю вам и так все понятно стало. Хотя мне самому это смутно ясно.
[youtube]http://www.youtube.com/watch?v=t3JtYnWR23E[/youtube]