c++ - 仅具有函数的菱形多重继承

标签 c++ inheritance

我想讨论一个 C++ 中的继承问题。 基本思想是有一个具有属性的基类和具有此属性访问器的不同子类。在底部应该是一个类,它将子类合并为一个。它是菱形,这会引入一些问题。

class A {
public:
  A() { prop = 1; }
  int prop;
};

class B : public A {
public:
  int getProp() { return prop; }
private:
  B();
};

class C : public A {
public:
  int setProp(int v) { prop = v; }
private:
  C();
};

class D : public B, public C {
private:
  D();
};

usage() {
  A* a = new A();
  B* b = (B*)a; // Works
  b->getProp(); // Works
  D* d = (D*)a; // This fails, because of diamond inheritance
  d->setProp(5);// This is kindof the goal
  d->getProp();// This is kindof the goal
}

所以,我已经阅读了一些关于虚拟继承的内容,但是我无法实现到 D 的转换,它应该包括 B 和 A 的所有方法。也许我在那里遗漏了一些东西。

另一方面。我真的只有 B 类和 C 类中的函数,所以通常可以通过采用类实例的静态包装器来实现这些访问器。但我想请您提供一些想法,以在没有任何包装器的情况下实际实现它,包装器将原始 A 作为参数。

编辑 1: 我将为您提供一些场景来阐明我想要实现的目标。 想象项目 A、B、C、D 和 E

Project_A contains Class_A. This class contains some member variables.
P_A also creates 5 instances of the class.
Project_C contains Class_C.
P_C also asks P_A to get the 5 instances of C_A.
P_C sets the properties of the 5 instances via its accessors.
Project_B contains Class B.
P_B asks P_A to get the 5 instances of C_A.
P_B gets the properties of the 5 instances.
Project_D contains Class D.
P_D does set and get the properties via the accessors of C_B and C_C.
Project_E contains Class E.
Project_E works on a different property of A.

P_B knows P_A
P_C knows P_A
P_D knows P_A, P_B, P_C
P_E knows P_A

这些项目由不同的各方共同开展。

也许这有帮助。也许不是。让我们来看看。

编辑 2: 这是另一个伪代码示例。也许这样对你来说更有意义。关键可能是,A 不知道它拥有哪些属性。 (或者更准确地说,它们的意思)

class A {
    map<int, int> props;
}

class B : private A {
    getProp1() { return props(1)}
    setProp1(int prop) { props(1) = prop }
}

class C : private A {
    getProp2() { return props(2)}
    setProp2(int prop) { props(2) = prop }
}

class D : public B, public C {
  // This is just a combination of B and C for comfort.
}

class E : private A {
    getProp3() { return props(3)}
    setProp3(int prop) { props(3) = prop }
}

最佳答案

B和C必须虚拟继承自A

class A {
public:
  A() { prop = 1; }
  int prop;
};

class B : virtual public A {
public:
  int getProp() { return prop; }
private:
  B();
};

class C : virtual public A {
public:
  int setProp(int v) { prop = v; }
private:
  C();
};

class D : public B, public C {
private:
  D();
};

usage() {
  A* a = new D(); //!!!! NEW D here
  B* b = dynamic_cast<B*>(a); // 
  b->getProp(); // 
  D* d = dynamic_cast<D*>(a); // Not diamond inheritance in cause, bad init of a!
  d->setProp(5);// 
  d->getProp();//
}

此外,使用 C++ 转换(dynamic_cast、static_cast、...)。如果你使用它,当你尝试转换时它会返回一个 nullptr A* a=new A()B 您应该测试 dynamic_cast 的结果。有了引用,dynamic_cast 抛出异常。一个A实例可以是 B实例。但是一个DB , 或 C实例可以是 A实例。和 D也可以是 CD实例。

关于c++ - 仅具有函数的菱形多重继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35629042/

相关文章:

c++ - 为什么这个 move 构造函数如此贪婪?

c++ - 无需继承直接访问类接口(interface)中成员的成员

c++ - 文件流构造函数

c++ - C++模板:尖括号中的类型名和|| s

c++ - 无法解析标识符 stoi

c++ - VS2013 中来自 xstring 的 OpenCV HoughCircles 示例(C++)中的调试断言失败

javascript - 在sails.js Controller 中调用 super 方法

postgresql - 在同一事件上触发之前和之后?填充子表 PostgreSQL

python - 在类定义中添加参数

javascript - 为什么对象不通过原型(prototype)链继承方法?