virtual constructor is possible?

0.可以吗?

我们不能让构造函数变成virtual的。C++语言的创造者stroustrup博士给出了很好的解释:virtual是一项使用部分信息就完成工作的技术,我们在调用virtual function时,只需要知道他的接口,而不需要知道他的具体对象。而构造函数在调用时需要知道对象的所有信息,这与virtual的技术相悖。

1.间接实现virtual constructor

我们可以在类中提供一个创建对象的virtual function来实现这个功能,例如:

class Expr r {
public:
    Expr() ; / / default constructor
    Expr(const Expr&) ; / / copy constructor
    virtual Expr* ne w_expr() { return ne w Expr() ; }
    virtual Expr* clone() { return ne w Expr(*this) ; }
};

将构造对象的member function设成virtual的,他就是"virtual constructor"。

2.factory design pattern

假设library端提供一个方法,client端只需要提供简单的信息,就可以完成对应的操作,同时对client端完全隐藏library端的信息,这就是factory design pattern,他是利用virtual来实现的,看一个简单的例子:

//factory.h
namespace design_pattern {
    enum class shape_cate {
        SQUARE,
        ROUND,
    };
    class shape {
    public:
        virtual ~shape();
        virtual void draw() const = 0;
        static shape* createShape(shape_cate cate);
    };

    class square :public shape {
    public:
        virtual void draw() const override;
        ~square();
    };

    class round :public shape {
    public:
        virtual void draw()const override;
        ~round();
    };

    class user {
    public:
        user(shape_cate cate);
        void drawTheShape()const;
        ~user();
    private:
        shape_cate c_;
        shape* s_ = nullptr;
    };
}
//factory.cpp
namespace design_pattern {
    shape::~shape() {

    }

    shape* shape::createShape(shape_cate cate) {
        if (cate == shape_cate::SQUARE) {
            return new square();
        }
        else if (cate == shape_cate::ROUND) {
            return new round();
        }
        else {
            return nullptr;
        }
    }

    void square::draw() const {
        std::cout << "-----" << std::endl;
        std::cout << "|   |" << std::endl;
        std::cout << "|   |" << std::endl;
        std::cout << "-----" << std::endl;
    }

    square::~square() {
        std::cout << "delete square" << std::endl;
    }

    void round::draw() const {
        std::cout << "round" << std::endl;
    }

    round::~round() {
        std::cout << "delete round" << std::endl;
    }

    user::user(shape_cate cate) {
        s_ = shape::createShape(cate);
    }

    void user::drawTheShape() const {
        if (s_) {
            s_->draw();
        }
    }

    user::~user() {
        if (s_) {
            delete s_;
            s_ = nullptr;
        }
    }
}

client端只需要提供图形的类型,利用library端提供的一个static方法,就可以构造不同的shape,调用他们去做一些工作,而client完全不知道他构造的square是什么样的。如果library端再次添加新的图形,client端也不需要更改任何代码。据高手们说,这种就叫decoupling,听上去好高级。

参考文献

[1]why do we not have a virtual constructor in c++
[2]Stroustrup B. The C++ Programming Language, Third Edition[C]// 1997.
[3]factory method

你可能感兴趣的:(virtual constructor is possible?)