接着上一课分析 ......
多重继承的问题三
多重继承可能产生多个虚函数表
示例:
class BaseA
{
public:
virtual void funcA()
{
cout << "BaseA::funcA()" << endl;
}
};
class BaseB
{
public:
virtual void funcB()
{
cout << "BaseB::funcB()" << endl;
}
};
class Derived : public BaseA, public BaseB
{
public:
void func()
{
cout << "Derived::funcB()" << endl;
}
};
int main()
{
Derived d;
cout << "sizeof(d) = " << sizeof(d) << endl; // 两个虚函数表指针
BaseA *pa = &d;
BaseB *pb = &d;
pa->funcA();
pb->funcB();
cout << endl;
BaseB *pbc = (BaseB*)pa;
BaseB *pbd = dynamic_cast<BaseB*>(pa);
cout << "Except funcB(), result: " ;
pbc->funcB();
cout << endl;
cout << "Except funcB(), result: " ;
pbd->funcB();
cout << endl;
cout << "pa = " << pa << endl;
cout << "pb = " << pb << endl;
cout << "pbc = " << pbc << endl;
cout << "pbd = " << pbd << endl;
return 0;
}
输出结果
sizeof(d) = 16 // 64位虚拟机
BaseA::funcA()
BaseB::funcB()
Except funcB(), result: BaseA::funcA()
Except funcB(), result: BaseB::funcB()
pa = 0x7ffcb86e0cc0
pb = 0x7ffcb86e0cc8
pbc = 0x7ffcb86e0cc0
pbd = 0x7ffcb86e0cc8
在需要进行强制类型转换时, C++中推荐使用新式类型转换关键字
解决方法: dynamic_cast
Derived d;
BaseA *pa = &d;
BaseB *pb = &d;
BaseB *pbb = dynamic_cast<Base*>(pa);
实际开发中采用“多重继承”这种方案
单继承某个类 + 实现(多个)接口
示例:
#include <iostream>
#include <string>
using namespace std;
class Base
{
protected:
int mi;
public:
Base(int i)
{
mi = i;
}
int getI()
{
return mi;
}
bool equal(Base *obj)
{
return (this == obj);
}
};
class Interface1
{
public:
virtual void add(int i) = 0;
virtual void minus(int i) = 0;
};
class Interface2
{
public:
virtual void multiply(int i) = 0;
virtual void divide(int i) = 0;
};
class Derived : public Base, public Interface1, public Interface2
{
public:
Derived(int i) : Base(i)
{
}
void add(int i)
{
mi += i;
}
void minus(int i)
{
mi -= i;
}
void multiply(int i)
{
mi *= i;
}
void divide(int i)
{
if( i != 0 )
{
mi /= i;
}
}
};
int main()
{
Derived d(100);
Derived *p = &d;
Interface1 *pInt1 = &d;
Interface2 *pInt2 = &d;
cout << "p->getI() = " << p->getI() << endl; // 100
pInt1->add(10);
pInt2->divide(11);
pInt1->minus(5);
pInt2->multiply(8);
cout << "p->getI() = " << p->getI() << endl; // 40
cout << endl;
cout << "pInt1 == p : " << p->equal(dynamic_cast<Base*>(pInt1)) << endl;
cout << "pInt2 == p : " << p->equal(dynamic_cast<Base*>(pInt2)) << endl;
return 0;
}
工程有用建议
- 先继承自一个父类,然后实现多个接口
- 父类中提供 equal 成员函数
- euqal() 成员函数用于判断指针是否指向当前对象
- 与多重继承相关的强制类型转换使用 dynamic_cast 完成
- 接口仅仅定义公有的接口函数而已
小结
- 多继承中可能出现多个虚函数表指针
- 与多继承相关的强制类型转换用 dynamic_cast 完成
- 工程开发中采用"单继承多接口" 的方式使用多继承
- 父类提供成员函数用于判断指针是否指向当前对象