Предыдущий пост -
Следующий пост -

“Виртуальные конструкторы”.

Рубрика: C++, Дата: 21 April, 2013, Автор:

Есть такое понятие в С++ как виртуальные конструкторы. Я щас как раз читаю эту тему и пытаюсь понять, что это такое, но увы как то мне щас это тяжко дается. Хз чо так. Да и вообще виртуальный деструктор я тоже не знаю что это такое, но давайте хотя бы щас разберемся с виртуальными конструкторами.

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

Я конечно строчки выше не полностью понял их смыл. Это я их так для массовки добавил. Ладно давайте посмотрим примерчик:

//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]

rss