一些C ++材料提及我们无法在CTOR或DTOR中称为虚拟功能,

(
抱歉,我认为最好更改为
一些C ++材料提及我们最好不要在CTOR或DTOR中调用虚拟功能,

)

但是我们可能会偶然地称他们为。有什么方法可以防止这种情况吗?

例如:

# include < iostream >  
using namespace std;  

class CAT  
{  
public:  
    CAT(){ f();}  
    virtual void f(){cout<<"void CAT:f()"<<std::endl;}  
};  

class SMALLCAT :public CAT  
{  
public:  
    SMALLCAT():CAT()  
    {  
    }  
    void f(){cout<<"void SMALLCAT:f()"<<std::endl;}    
};    

int main()  
{  
    SMALLCAT sc;   

}  

输出:

void CAT::f()  //not we expected!!!

谢谢

没有正确的解决方案

其他提示

您需要将这些“ C ++材料”扔到垃圾桶。

你当然 能够 调用构造函数或破坏者的虚拟函数。他们将完成工作。您只需要意识到语言规范,这些语言规范明确指出了虚拟调度机制根据 当前的 对象的动态类型,而不是其 最后 预期的动态类型。对于正在构造/破坏的对象而言,这些类型不是相同的,当新手试图从构造函数/破坏者中调用虚拟功能时,它们通常会混淆。然而,只要您知道他们的工作以及在这种情况下它们的工作方式,调用构造函数和驱动器的虚拟函数是该语言的有用功能。您为什么要“防止”它?

这就像说分区运营商很危险,因为人们可以将某些东西除以零,并询问如何“防止”其在程序中的使用。

您可以在破坏者中调用虚拟函数。只有在某些情况下,它行不通,并且可能会崩溃您的程序。避免打电话给他们的方法是不给他们打电话。除了可能有一些静态分析工具来查看您的代码并警告您此类潜在问题之外,我还不知道一些奇特的东西。

您当然可以在CTOR/DTOR中调用虚拟函数。问题是您的VTable是在每个构造函数(和Destructor)中设置的,因此您的虚拟功能调用将调用当前正在设置的类的实现。如果那是你想要的,很酷。但是,您不妨保存自己的VTable查找并进行范围调用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top