例如我有两个班级
A类:
class A
{
private:
int a;
}
子类B:
class B: private A
{
private:
char b;
public:
char getB();
}
代码:
int main()
{
A* item = new B();
char b = (B)item->getB();
}
如果我需要做类似的事情,我应该使用演员表还是重新设计节目?我不想使用多态。
答案 0 :(得分:4)
问题
1)B私下继承自A.所以只有B才能将B*
强加给A*
。
2)表达式的优先级与(B)(item->getB());
相同所以这不会编译,因为item
是A
而A没有成员getB()
。
3)最好使用static_cast
或dynamic_cast
而不是旧的C样式演员。
解决方案
1)如果要在类本身之外的派生类和基类之间进行转换,请使用公共继承。
2)然后使用括号:
char b = ((B*)item)->getB();
3)或者更喜欢更精确的形式:
char b = static_cast<B*>(item)->getB();
4)但是当你这样做垂头丧气时,你需要自担风险。如果A*
指针指向的不是B或从B派生的类,那么它是未定义的行为。
当你考虑对你的类型进行多态使用时,你最好有一个虚拟析构函数,这样你就可以用适当的析构函数删除项目(这里它会使用A的析构函数而不是B的)。
只要您拥有至少一个虚拟功能,就可以使用更安全的dynamic_cast:
if(dynamic_cast<B*>(item)) { // would be nullptr if item doesn't point to a B object
char b = dynamic_cast<B*>(item)->getB();
... // further processing of the char
}
else cout << "Ooops!"<<endl;
答案 1 :(得分:2)
你应该使用dynamic_cast
安全地在继承层次结构(cppreference.com)上向上,向下和横向转换指针和类的引用:
dynamic_cast<B*>(item)->getB();
,而不是旧式C cast:
((B*)item)->getB();
修改强>
您应该使用公共继承来使用dynamic_cast
。出于什么目的使用private
继承?在你的例子中,它没有多大意义恕我直言。使用没有虚拟析构函数的继承也很危险。