多重虚继承C++
Multiple virtual inheritance C++
我在多重继承方面遇到了问题,如果有人能帮助我,那就太好了。我正在编写一个最终归结为类似于此的情况
class A {
public:
A(){}
virtual ~A() = 0;
virtual void print()=0;
};
A::~A(){}
class B: public virtual A {
public:
B():A(){}
virtual ~B() = 0;
virtual void print() {
cout << "Hello" << endl;
}
};
B::~B(){}
class C: public virtual A {
public:
C():A(){}
virtual ~C() = 0;
virtual void print () {
cout << "Bye" << endl;
}
};
C::~C(){}
class D: public B, public C {
public:
D():B(),C(){}
virtual ~D(){}
virtual void print(){}
};
int main()
{
D d;
A* a = &d;
a->B::print(); //The statement leads to errors
a->C::print(); //The statement leads to errors
}
我需要访问 class B 和 class C 中虚函数的实现。有没有办法做到这一点?
类型 A
根本不知道子类 B
和 C
中的实现。要调用这些成员,您首先必须将 a
转换为至少 B
或 C
,甚至转换为 D
:
D* aAsD = dynamic_cast<D*>(a);
if (aAsD) {
aAsD->B::print();
aAsD->C::print();
}
A *a
不知道 B
或 C
中的 print()
。您可能希望 D
处理是否调用 B::print()
或 C::print()
.
class D: public B, public C {
public:
D():B(),C(){}
virtual ~D(){}
virtual void print()
{
B::print(); //or some logic to call one of them
C::print();
}
};
和
D d;
A* a = &d;
a->print();
像那样做 B::Print 或 C::print 的整个愿望似乎有些不对......尤其是当你让它成为 D 中的空操作时。
这表明也许 D 不应该继承 B 和 C,而是包含一个 B 和一个 C。然后您可以将 B 和 C 与 D 分开公开,这可以作为 A 单独传递。
显然这可能不适用于您的扩展问题,但适用于您发布的问题;我会称之为继承滥用。
要理解这一点,请暂时忽略继承:
- Class 'A' 没有打印方法
- Class 'B'和'C'有自己的打印方式
- Class 'D'本身没有打印方法
现在将继承添加到等式中:
- Class'D'继承了'B'和'C',所以它有两种打印方式
- Class 'B'和'C'继承了'A',但是由于'A'没有打印方法,所以它们仍然有相同的方法
- Class 'A' 没有打印方法。
当您转换 A* a = &d
时,您正在将具有两种打印方法的 class 转换为没有打印方法的 class。由于继承的力量,'A' class 打印方法现在被 'D' class 中的方法重载,但 'a' 变量仍然是一个 'A' class(来自 'D' 的重载)。由于 'A' 不继承 'B' 或 'C',它不知道它们是什么。尝试使用它们时出现错误的原因。
解决这个问题的方法就是不将 'D' 转换为 'A':
int main() {
D d;
d.B::print(); //Hello
d.C::print(); //Bye
}
此外,如果您需要将 'D' 转换为 'A',您应该将其相应地转换为 B 或 C:
int main() {
D d;
A* a = &d;
dynamic_cast<B*>(a)->B::print();
dynamic_cast<C*>(a)->C::print();
}
或 1 个动态转换版本:
int main() {
D d;
A* a = &d;
D* dptr = dynamic_cast<D*>(a);
dptr->B::print();
dptr->C::print();
}
换句话说,在分别使用'C'和'B'之前,你必须将'a'向上转换为继承'C'和'B'的东西
我在多重继承方面遇到了问题,如果有人能帮助我,那就太好了。我正在编写一个最终归结为类似于此的情况
class A {
public:
A(){}
virtual ~A() = 0;
virtual void print()=0;
};
A::~A(){}
class B: public virtual A {
public:
B():A(){}
virtual ~B() = 0;
virtual void print() {
cout << "Hello" << endl;
}
};
B::~B(){}
class C: public virtual A {
public:
C():A(){}
virtual ~C() = 0;
virtual void print () {
cout << "Bye" << endl;
}
};
C::~C(){}
class D: public B, public C {
public:
D():B(),C(){}
virtual ~D(){}
virtual void print(){}
};
int main()
{
D d;
A* a = &d;
a->B::print(); //The statement leads to errors
a->C::print(); //The statement leads to errors
}
我需要访问 class B 和 class C 中虚函数的实现。有没有办法做到这一点?
类型 A
根本不知道子类 B
和 C
中的实现。要调用这些成员,您首先必须将 a
转换为至少 B
或 C
,甚至转换为 D
:
D* aAsD = dynamic_cast<D*>(a);
if (aAsD) {
aAsD->B::print();
aAsD->C::print();
}
A *a
不知道 B
或 C
中的 print()
。您可能希望 D
处理是否调用 B::print()
或 C::print()
.
class D: public B, public C {
public:
D():B(),C(){}
virtual ~D(){}
virtual void print()
{
B::print(); //or some logic to call one of them
C::print();
}
};
和
D d;
A* a = &d;
a->print();
像那样做 B::Print 或 C::print 的整个愿望似乎有些不对......尤其是当你让它成为 D 中的空操作时。
这表明也许 D 不应该继承 B 和 C,而是包含一个 B 和一个 C。然后您可以将 B 和 C 与 D 分开公开,这可以作为 A 单独传递。
显然这可能不适用于您的扩展问题,但适用于您发布的问题;我会称之为继承滥用。
要理解这一点,请暂时忽略继承:
- Class 'A' 没有打印方法
- Class 'B'和'C'有自己的打印方式
- Class 'D'本身没有打印方法
现在将继承添加到等式中:
- Class'D'继承了'B'和'C',所以它有两种打印方式
- Class 'B'和'C'继承了'A',但是由于'A'没有打印方法,所以它们仍然有相同的方法
- Class 'A' 没有打印方法。
当您转换 A* a = &d
时,您正在将具有两种打印方法的 class 转换为没有打印方法的 class。由于继承的力量,'A' class 打印方法现在被 'D' class 中的方法重载,但 'a' 变量仍然是一个 'A' class(来自 'D' 的重载)。由于 'A' 不继承 'B' 或 'C',它不知道它们是什么。尝试使用它们时出现错误的原因。
解决这个问题的方法就是不将 'D' 转换为 'A':
int main() {
D d;
d.B::print(); //Hello
d.C::print(); //Bye
}
此外,如果您需要将 'D' 转换为 'A',您应该将其相应地转换为 B 或 C:
int main() {
D d;
A* a = &d;
dynamic_cast<B*>(a)->B::print();
dynamic_cast<C*>(a)->C::print();
}
或 1 个动态转换版本:
int main() {
D d;
A* a = &d;
D* dptr = dynamic_cast<D*>(a);
dptr->B::print();
dptr->C::print();
}
换句话说,在分别使用'C'和'B'之前,你必须将'a'向上转换为继承'C'和'B'的东西