2在构造函数中调用纯虚函数会出错?

时间:2014-04-09 00:05:43

标签: c++

class A{
public:
A(){
this->draw();
}
  virtual void draw()=0;
};

是否会导致编译错误。如果是的话,为什么。如果不是,为什么?

2 个答案:

答案 0 :(得分:0)

首先,从构造函数中调用纯虚拟是Undefined Behavior。

C ++11§10.4/ 6:

  

“制作的效果   对正在创建(或销毁)的对象直接或间接虚拟调用(10.3)纯虚函数   来自这样的构造函数(或析构函数)是未定义的。“

然后你的问题是,如果UB一般需要诊断。

没有。

虽然注释不是规范,但C ++11§1.3.24中的以下注释阐明:

  

“允许的未定义行为   范围从完全忽略情况与不可预测的结果,到翻译期间的行为或   程序以环境特征的文件形式执行(有或没有发行   诊断消息)“

您的编译器,使用您选择的特定选项,可能会也可能不会发出诊断信息,然后可能会也可能不会生成可执行文件。如果是这样,构造函数的执行可能会或可能不会导致一些运行时错误。简而言之,它是未定义的行为。


为什么是未定义的行为?例如,为什么它不能在派生类中调用实现?

好吧,如果可以,那么派生类中的代码可以在派生类实例初始化之前执行,这意味着可以执行有关实例变量值的错误假设,这意味着它很容易导致错误。

这就是例如Java和C#。

但是,在C ++中,使用动态类型 T的{​​{1}}对象执行类*this的构造函数或析构函数中的代码执行。这里对虚函数的调用具有与相同的效果,就像对象最初被实例化为T一样(即使T具有纯虚函数)。这可以确保代码的效果与派生类中的功能无关,因为T程序员真的知道你手头有什么。

使用这些更安全的类型规则,不能有纯虚函数的任何派生类实现,因为在此上下文中没有对象的派生类部分:它纯粹是T对象。 / p>

答案 1 :(得分:0)

是的,它会导致错误。

纯虚函数用于使您的类抽象,这意味着从该类继承的任何类都必须实现您的虚函数。

例如,假设你有一个继承自A类的B类,你必须在那里实现draw()方法,你可以在那里调用它。但是你永远不会在它定义的类中调用纯虚函数。