c++ - 为什么纯虚拟/抽象类需要构造函数,特别是对于 protected const 成员变量?

标签 c++ constants abstract-class pure-virtual

我有一个这样定义的纯虚拟类:

class BaseClass {
 protected:
  const int var;
 public:
  void somefun() = 0; // what I mean by a purely virtual class
  // stuff...
};

如果我不添加这样定义的构造函数:

BaseClass(const int & VAR) : var(VAR) {};

我必须随后在派生类中使用,我的派生类无法将 const 变量 var 初始化为它想要的任何值。现在我真的明白这里发生了什么。在构造派生类之前,会调用基类的构造函数,此时必须初始化 const 成员变量。我的问题不是“我如何使我的代码工作”之类的问题,这已经完成了。我的问题是关于为什么编译器认为这是必要的。对于一个纯虚拟类,我不应该被允许写这样的东西:

class DerivedClass : BaseClass {
 public:
  DerivedClass() : var(SOME_VALUE) {};
}

如果编译器知道调用 BaseClass 构造函数之后必然会调用某个派生类构造函数(因为抽象类型的对象永远无法实例化),难道它不应该给我们更多的回旋余地吗?

这都是 C++ 选择绕过菱形继承(钻石问题)的结果吗?即使是这样,编译器是否应该至少以某种方式允许在派生类中定义纯虚函数的 const 成员变量的可能性?这是否太复杂了,或者是否与 Diamond 问题的 C++ 解决方案混淆了?

感谢大家的帮助。

最佳答案

它不是“纯虚拟的”(不管你是什么意思)——它包含一个数据成员。

类成员只能由该类的构造函数的初始化列表初始化,不能由派生类的构造函数初始化。这就是指定对象初始化的方式:所有初始化的成员都在构造函数主体开始之前初始化。

必须初始化常量对象,因为以后不能为它们赋值。

因此,具有常量数据成员的类必须在每个构造函数中初始化它。

关于c++ - 为什么纯虚拟/抽象类需要构造函数,特别是对于 protected const 成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9399290/

相关文章:

c++ - 覆盖 - 如何用更少的打字来做到这一点?

c++ - 这些有什么区别?

objective-c - 在指向对象的指针之前,const 说明符有什么作用?

c# - 如何在 C# 中创建一个 public const Size?

c++ - 在这个 C++ 函数中更新 Fortran 中的两个数组

c++ - std::atomic<int> - 以原子方式加载并重置为 0?

c++ - 在 C++ 中定义复数常量 "i"(#define 与 const)

c++ - 是否可以使用 googletest 在基类中定义(纯虚拟)测试用例

c# - 仅部分实现抽象类的接口(interface)时如何满足编译器?

java - IntBuffer(和其他原始类型缓冲区)的工厂方法返回实例,但这些类实际上是抽象定义的