当丢失非const虚拟方法时,为什么我不能实例化类的const实例



为什么这个不合法?

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

  • 我可以在施放超级/子类的情况下遇到麻烦吗?

如果不是,那为什么必须定义它?

我认为有几种钝的方法可以放置:

  1. ,因为只有一个vtable。const和non-const对象共享。

  2. ,因为您可能会 const_cast const const对象。

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

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

其他问题是:

是否允许使用const_cast?

是。但是,您对const_casted参考的处理可能会迅速导致"未定义的行为"。这并不意味着"世界可能会结束",正如您相信的那样。它的含义是:" C 标准不能定义此行为 - 如果编译器,硬件或操作系统希望,这取决于它们"。即,您对该const_casted参考的方法不太可能是可移植的。

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

演员是麻烦的开放邀请。

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

最新更新