虚拟课题

时间:2010-05-02 16:52:58

标签: c++ class polymorphism virtual

我对虚拟类的看法是,如果派生类有公共基础,比方说,类base,则可以将指向派生的指针分配给指向base的类型指针的变量,而不使用任何显式类型转换。但是,如果我们在基类内部那么我们如何调用派生类的函数呢?我举一个例子:

class Graph{
  public:
    Graph(string);
    virtual bool addEdge(string,string);
}
class Direct:public Graph{
  public:  
    Direct(string);
    bool addEdge(string,string);
}
Direct::Direct(string filename):Graph(filename){};

当我调用Direct类的构造函数时,它调用Graph。现在让我们想想图形函数调用addge。

Graph(string str){
    addedge(str,str);
}

当它调用addge时,即使该函数是虚函数,它也会调用Graph :: edge。我想要的是,调用Direct :: addedge。怎么办呢?

4 个答案:

答案 0 :(得分:3)

无法做到。虚函数不能在构造函数中调用 - 至少它们不能用虚拟行为调用。问题是派生类构造函数负责设置vtbl以指向它的虚函数的特定实例。基类的构造函数首先在派生的构造函数之前执行,因此无法直接解决此问题。

您可以使用基类上的某种形式的“init”函数解决此问题,也可以使用工厂方法。

答案 1 :(得分:2)

在C ++中这是 by design ,请参阅C++ FAQ

在你的情况下,我也不明白你为什么需要它 - 如果你想使用初始化辅助函数,就不需要它是虚拟的。

答案 2 :(得分:1)

您在Scott Meyer的Effective C ++中的解释是here

不要在构造或销毁期间调用虚函数,因为此类调用永远不会转到比当前正在执行的构造函数或析构函数更多的派生类。

答案 3 :(得分:0)

您希望基类型的构造函数通过虚方法调用派生类型。这很麻烦,因为衍生类型尚未完全构建。当类型尚未构造时,派生类型的重写虚拟函数将用于什么状态?您可能希望查看另一种设计模式,例如工厂,如果您真的需要它,可以封装两步构造/初始化模式。