use*_*129 5 c++ oop multiple-inheritance
我从来没有使用多重继承,偶然发现了一个我从未遇到过的设计问题.
class A {
//..methods..
}
class B : public A {
int b;
//...methods..
}
class C : public A {
int c1,c2;
}
class D : public B,public C {
}
Run Code Online (Sandbox Code Playgroud)
这是经典的钻石.事实是,这C真的只是一个A额外的两个整数.而D实际上只是一个聚集B和C,但我觉得多重继承并不是用来做这样的事情.或者可能还有其他最佳做法可以做到这一点.
我试图实现多重继承的原因是我想编写一个类似的函数void func(A*)并将其传递给一个A或D类指针.我的天真尝试是做一个简单的演员:
void func(A* a) { // <-- I call this with a A or D pointer
// ..do something with A members..
if(is_the_case) { // <-- Im sure the passed "a" pointer is actually a *D
D* d = (D*)a;
// ..do something with the extra 2 ints provided by the C class..
}
}
Run Code Online (Sandbox Code Playgroud)
不起作用..编译很好,但是if(is_the_case)执行时我有一个非常奇怪的行为,清除了2个额外的int,c1并且c2也清除了b(继承B).
我重新考虑钻石问题,但这里只有一个B(和2个A)层次结构,所以我不明白为什么要b清除它.只是为了尝试,我使用了公共虚拟B和C声明.现在每个演员都是编译错误,除非我使用dynamic_cast..
有人能说清楚幕后发生了什么吗?考虑到还有其他课程,最好的做法是什么:
class E : public A {
int e;
//..methods..
}
class F : public E,public C {
}
Run Code Online (Sandbox Code Playgroud)
也就是说,其他类只是一个类的聚合,派生自A+继承的两个额外的int,C并且可以传递给一个需要的函数*A
谢谢,尽我所能尽可能清楚..
您的代码之所以有效,是因为您使用了 C 风格的强制转换,它可以是 a reinterpret_cast,并且据我所知,您可以reinterpret_cast在任意两个指针类型之间进行转换,即使它没有意义。dynamic_cast从多重继承的基类转换为更派生的类时,必须使用 a 。Astatic_cast会产生编译时错误。事实上,dynamic_cast它同时完成两项工作。
void func(A* a) { // <-- I call this with a A or D pointer
// ..do something with A members..
if(D* d = dynamic_cast<D*>(a)) { // a definitely points to a D
// and we got a guaranteed good pointer too
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好的例子,说明了为什么应该避免 C 风格的强制转换。