我有一个基类 A,两个子类 B 和 C,它们都继承自 A,我有一个继承自 B 和 C 的类 D,其中我想从 B 中获取 _a 并从 C 中获取 _b,而不必如果可能,为 print_a 和 print_b 做一个虚拟方法
# include <iostream>
class A
{
public:
A(void) : { }
~A(void) { }
inline void print_a(void) { std::cout << _a << std::endl; }
inline void print_b(void) { std::cout << _b << std::endl; }
protected:
int _a;
int _b;
};
class B : virtual A
{
public:
B(int a) : A() { _a = a, _b = 0; }
~B(void) { }
protected:
using A::_a;
using A::_b;
};
class C : virtual A
{
public:
C(int b) : A() { _a = 0, _b = b; }
~C(void) { }
protected:
using A::_a;
using A::_b;
};
class D : virtual public A, private B, private C
{
public:
D(void) : A(), B(5), C(5) { }
~D(void) { }
private:
using B::_a;
using C::_b;
};
int main(void)
{
D foo;
foo.print_a();
foo.print_b();
return (0);
}
我的 D 类从 A 继承方法 print_a 和 print_b,我希望它从 B 继承 _a = 5 和从 C 继承 _b = 5,但它不起作用,它输出:
0
5
代替:
5
5
答案 0 :(得分:2)
当您对所有基类使用 virtual
时,您最终得到的 D
只有一个 A
(而不是一个作为 D
的基类,一个作为 B
的基类) C
和一个作为 D::D
的基础)。
问题出在你的构造函数上。
派生类的构造函数按照基类列表中给出的顺序调用所有基类的构造函数,因此在您的情况下 A::A() -> _a and _b uninitialized
B::B(5)
_a = 5
_b = 0
C::C(5)
_a = 0
_b = 5
调用:
_a
不清楚为什么要在不同的构造函数中多次设置 _b
和 A(int a, int b) : _a(a), _b(b) {}
B(int a) : A(a, 0) {}
C(int b) : A(0, b) {}
D() : A(5, 5), B(5), C(5) {}
。最好在构造函数的成员初始值设定项列表中初始化成员,而不是在构造函数体中分配它。例如你可以写
D::D()
此处 A(5, 5) -> _a initialized to 5, _b initialized to 5
B(5) -> no effect (on A/_a/_b)
C(5) -> no effect (on A/_a/_b)
将导致
D::D
如果你想坚持你的设计并初始化构造函数体中的变量,你可以简单地将代码添加到 D() : A(), B(5), C(5) { _a=5; _b=5; }
以覆盖基类构造函数设置的任何内容:
html