Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 397, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

如何实现虚构造

如果想在构造函数中调用虚函数,必须来模拟虚构造函数。注意是虚拟并不是真正的虚构造函数
#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++中提出的用虚拷贝构造函数实现的方法,基类是个抽象基类,个人感觉上面的实现更好些。

posted on 2009-04-19 22:18 Benjamin 阅读(447) 评论(2)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 如何实现虚构造  回复  更多评论   

囧,这是一种奇怪的factory
2009-04-20 14:15 | 陈梓瀚(vczh)

# re: 如何实现虚构造  回复  更多评论   

@陈梓瀚(vczh)
- -,居然在这发现你,,,
2009-08-14 17:30 | MartySa

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理