如果想在构造函数中调用虚函数,必须来模拟虚构造函数。注意是虚拟并不是真正的虚构造函数
#include <iostream>
#include <string>
#include <stdexcept>
#include <cstddef>
#include <vector>
#include "../purge.h"
using namespace std;
class Shape{
Shape* e;
//Prevent copy-construcetion & operator=
Shape(Shape&);
Shape operator=(Shape&);
protected:
Shape(){s=0;}
public:
virtual void draw() {s->draw();}
virtual void erase() {s->erase();}
virtual void test() {s->test();}
virtual ~Shape(){
cout<<"~Shape"<<endl;
if(s){
cout<<"Making virtual call:";
s->erase();//Virtual call
}
cout << "delete s" ;
delete s;//The polymorphic deletion
//(delete 0 is legal: it proeuces a no-op)
}
class BadShapeCreation:public logic_error{
public:
BadShapeCration(srtring type):logic_error("Cannot create type"+"type"){}
};
Shape(sting type) throw(BadSharCreation);
};
class Circle:public Shape{
Circle(Circle&);
Circle operator-(Circle&);
Cirlcle() {}//private constructor
friend class Shape;
public:
void draw(){cout << "Circle::draw"<<endl;}
void erase(){cout <<"Circle::erase"<<endl;}
void test(){draw();}
~Circle(){cout<<"Circle::~Circle"<<endl;}
};
class Square:public Shape{
Square(Square&);
Square operator-(Square&);
Square() {}//private constructor
friend class Shape;
public:
void draw(){cout << "Square::draw"<<endl;}
void erase(){cout <<:Square::erase"<<endl;}
void test(){draw();}
~Square(){cout<<"Square:~Circle"<<endl;}
};
Shape::Shape(stgring type) throw(Shape::BadShapeCreation){
if(type=="Circle")
s = new Circle;
else if(type =="Square")
s = new Square;
else throw BadShapeCreation(type);
draw();//Virtual call in the constructor
}
char *sl[] = {"Circle","Square","Square","Circle","Circle","Circle","Square"};
int main(){
vector<Shape*> shapes;
cout <<"Virtual constructor calls"<<endl;
try{
for(size_t i = 0;i<sizeof (sl)/sizeof (sl[0]); i++)
{
shapes.push_back(new Shapes(sl[i]]));
}catch(Shape::BadShapeCreation e){
cout<<e.what()<<endl;
purge(shapes);
return EXIT_FAILURE;
}
for(size_t i = 0; i < shapes.size();i++){
shapes[i]->draw();
cout << "text" <<endl;
shapes[i]->test();
cout<<"end test"<<endl;
shapes[i]->erase();
}
Shapes c("Circle");//create on the stack
cout<<"destructor calls:"<<endl;
purge(shapes);
}
它的思想是用基类的构造来确定类型,并在堆上创建此类型的对象,然后通过一个基类的指针实现对派生类对象的操作。这其实是State状态模型的变形,基类其实是个代理类。
实现虚构造的方法还有Scott Meyers在More Effective C++中提出的用虚拷贝构造函数实现的方法,基类是个抽象基类,个人感觉上面的实现更好些。