我遇到过一种我以前从未见过的奇怪的C ++继承模式:
有两个接口A和B.每个接口有两个不同的实现,分别称为A1和A2,B1和B2。此外,接口AB继承自接口A和B,并且有两个派生类AB1和AB2使用实现A1和B1,A2和B2。
问题是:
如果我有一个AB指针,有没有办法分配AB1或AB2的指针?以下代码演示了此问题。它至少可以用g ++ 4.6或更高版本编译,但它会产生一个seg-fault。如果我使用动态强制转换运算符,则编译器接受从AB1 *到AB *的赋值。
#include <iostream>
// first interface and implementations
struct A
{
virtual void a() = 0;
};
struct A1 : public A
{
void a() { std::cout << "A1\n"; };
};
struct A2 : public A
{
void a() { std::cout << "A2\n"; }
};
// second interface and implementations
struct B
{
virtual void b() = 0;
};
struct B2 : public B
{
void b() { std::cout << "B2\n"; }
};
// combining interfaces and implementations
struct AB : public A, public B
{};
struct B1 : public B
{
void b() { std::cout << "B1\n"; }
};
struct AB1 : public A1, public B1
{};
struct AB2 : public A2, public B2
{};
int main()
{
AB1* ab1 = new AB1();
ab1->a();
ab1->b();
AB2* ab2 = new AB2();
ab2->a();
ab2->b();
// this code compiles but doesnt work
AB* ab;
ab = dynamic_cast<AB*>(ab1);
ab->a();
ab->b();
ab = dynamic_cast<AB*>(ab2);
ab->a();
ab->b();
return 0;
}
我最好的猜测是AB1,AB2和AB的对象布局不同。但是,为什么动态演员有效?
有人能指出我有关此代码模式的更多信息吗?
非常感谢, schluchtenbummler
答案 0 :(得分:2)
ab1
和ab2
都不能投放到AB
。如果无法执行强制转换,dynamic_cast
将返回NULL(如果使用C ++ 11,则返回nullp)。在尝试访问ab
之前,您应检查nullptr
。你在问题中说“动态演员为什么会起作用?”......答案是,它不起作用,但你没有检查返回值,看是否是这种情况。
答案 1 :(得分:0)
如果dynamic_cast<AB*>(x)
是指向动态类型不是0
的对象或其派生类型的指针,x
的结果将为AB
。由于AB
可能会在继承图中稍后注入,dynamic_cast
可用于跨层次结构转换,如果具体对象使用多重继承继承它们,编译器没有理由认为pounters'' t指向一个可能是AB
的对象。