为什么我不能在缺少非const虚方法时实例化类的const实例?

时间:2016-12-23 18:32:53

标签: c++ const virtual

为什么这不合法?

class Base {
public:
    virtual void bar() = 0;
    virtual void barc() const = 0;
};

class Derived: public Base {
public:
    // deliberately omitted
    // virtual void bar()
    virtual void barc() const override { };
};

int main() {
    const Derived b;
    b.barc();
    // b.bar();
    // fails as expected with "passing 'const Bar' as 'this' argument discards qualifiers"
}

这失败并出现以下错误,因为我没有定义virtual void bar()

prog.cpp: In function 'int main()':
prog.cpp:16:12: error: cannot declare variable 'd' to be of abstract type 'Derived'
  const Derived d;
            ^
prog.cpp:10:7: note:   because the following virtual functions are pure within 'Derived':
 class Derived : public Base{
       ^
prog.cpp:6:15: note:    virtual void Base::bar()
  virtual void bar() = 0;

但是我无论如何都不能在这里调用bar,因为该方法没有标记为const。如果定义了bar,是否有任何合法的方式间接调用d.bar()

  • 是否正在使用const_cast

  • 我可以在构建超级/子类时遇到麻烦吗?

如果没有,那为什么我要定义它?

2 个答案:

答案 0 :(得分:10)

我认为有一些直截了当的方法:

  1. 因为只有一个vtable。 const和非const对象共享它。

  2. 因为你可能const_cast const对象为非const对象。

  3. 因为在构造对象时,它不是常量。

  4. 因为constness不是对象本身的属性,所以它是附加到对象或引用的属性,用于限制对对象部分的访问。

  5. 进一步的问题是:

      

    是否允许使用const_cast?

    是。但是你用const_casted引用做的事情很快就会导致"未定义的行为"。这并不意味着"世界可能会结束,因为有些人会相信你。这意味着," c ++标准没有定义这种行为 - 如果编译器,硬件或操作系统希望这样做,那就是他们自己"。即,无论你使用const_casted引用做什么,都不太可能是可移植的。

      

    我可以在构建超级/子类时遇到麻烦吗?

    演员阵容是一个公开的邀请函。

答案 1 :(得分:6)

您无法实例化抽象类。故事结束。