c++ - 强制派生类覆盖数据成员

标签 c++

我有一个虚拟类 A,其中包含数据 valval2valA 设置,但 val2 应该由 A 的 child 设置(基于值val)。我想强制每个派生类设置val2。以下

#include<iostream>

class A {
  public:
    A(): val(1), val2(getVal2())
    {};

    int val;
    int val2;

    protected:
      virtual int getVal2() = 0;
  };

class B: public A {
  protected:
    virtual int getVal2() { return 2*val; };
};

int main(){
  B b;
  std::cout << b.val2 << std::endl;
}

是否工作,因为 A 的构造函数调用了一个当时尚未定义的函数 (getVal2):

/tmp/cc7x20z3.o: In function `A::A()':
test9.cpp:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0x1f): undefined reference to `A::getVal2()'
collect2: error: ld returned 1 exit status

强制派生类显式设置 val2 的更好方法是什么?

最佳答案

val2 作为基类构造函数中的参数(不要使用默认构造函数):

class A
{
  public:
    A(int _val2) : val(1), val2(_val2) {};

    A() = delete;     //for clarity, not required as it is implicitly deleted

    //...
    int val;
    int val2;
};

这需要派生类在它们的构造函数中设置val2:

struct B : public A
{
    B() : A(0) {}   //A must be initialized, thus val2 is set in any case
    // ...
};

不要尝试访问基类构造函数中的纯虚成员:它们尚未构造,因此尚不可访问;这会产生 undefined behaviour .


编辑:从评论来看,问题似乎实际上比 OP 中描述的更复杂。即:val 应在派生类构造函数初始化列表中可用(并且不应是静态的)。

我想到的最简洁的解决方案(其他人请参阅评论)是引入另一个基类并派生virtual:

struct Abase
{
    Abase() : val(1) {}
    int val; 
};

struct A : virtual Abase
{
    A(int _val2) : val2(_val2) {}
    int val2;
};

struct B : virtual A
{
    B() : /* Abase() is called implicitly here, */ A(2*val){}  
                                                 //^^^^^ now val is correctly initialized.
};

DEMO .

此外,您可以考虑继承 protected(因为至少 Abase 是一个实现细节,并不意味着要以多态方式使用)。

关于c++ - 强制派生类覆盖数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30848517/

相关文章:

c++ - V8 C++ 嵌入问题

c++ - 如何调试Linux中的踩踏问题

c++ - 在 C++ 中计算任何结构的简单方法

c++ - 访问子类变量的正确解决方案是什么?

c++ - 程序忽略输入

c++ - 试图将文件读入结构数组,但 for 循环仅显示第一个索引,其余索引为零?

c++ - 删除动态分配的数组与单个指针

c++ - 解决模板类之间的循环依赖

C++根据输入返回一个字符串或一个int

c++ - 在 C++ 中是否必须通过引用传递类