什么时候 child class 太不同而无法继承?

When is a child class too different to be inherited?

我有一组紧密联系的数据结构,感觉它们应该被继承。但是,它们的不同之处在于 children 有一些额外的变量。我可以通过以下方式实现:

struct A {
int a;
int b;
virtual int kind()=0;
A(int a_, int b_) : a{a_}, b{b_} {};
}

struct B: A {
int c;
int kind() {return 1;};
B(int a_, int b_, int c_) : A(a_, b_), c{c_} {};
}

struct C : A {
int d;
int kind() {return 2;};
C(int a_, int b_, int d_) : A(a_, b_), d{d_} {};
}

但是如果我想遍历这些向量并访问派生的变量 class 它开始变得有点混乱:

std::vector<A*> v;
v.push_back(new B(1,1,1));
v.push_back(new C(1,1,2));

for (A* bar : v) {
    if (bar->kind() == 1) {
        auto *bar_ = dynamic_cast<B*>(A);
        std::cout << bar_->c << std::endl;
    } else if (bar->kind() == 2) {
        auto *bar_ = dynamic_cast<C*>(A);
        std::cout << bar_->d << std::endl;
    }
}


这种情况正常吗,还是我遗漏了什么,违反了一些重要的规则?我找到的大多数继承示例都没有不同的重要成员变量或方法,只是相同的实现不同。

您已经完成了创建虚拟基地的工作class。您可以重载要执行单独操作的函数,而不是将类型作为值返回。

struct A {
  virtual ~A() = default;
  int a;
  int b;
  virtual int get_value() const = 0;
  A(int a_, int b_) : a{a_}, b{b_} {};
}

struct B: A {
  int c;
  int get_value() const override {return c;};
  B(int a_, int b_, int c_) : A(a_, b_), c{c_} {};
}

struct C : A {
  int d;
  int get_value() const override {return d;};
  C(int a_, int b_, int d_) : A(a_, b_), d{d_} {};
}

请注意,我在这里使用了 override 说明符。这是现代 c++ 中可读性和代码安全性的良好做法。

现在,我们可以使用虚函数来简化主代码

std::vector<A*> v;
v.push_back(new B(1,1,1));
v.push_back(new C(1,1,2));
        
for (auto* bar : v) {
  std::cout << bar->get_value() << std::endl;
}

// ... do something else with v

// clean up the memory

for (auto *bar : v) {
  delete bar;
}

记得在基类中定义一个虚析构函数class。这确保当我们删除向量 v 中的 A* 时,继承的 class 的析构函数也会被调用,并且我们不会发生内存泄漏。