我在C ++中有这个父类
//ParentClass header file
public ParentClass{
public:
ParentClass();
virtual void someParentFunction();
private:
//other member variables and functions
};
//Functions implemented done in respective .cpp file
我扩展了这个课程,所以我有一个看起来像这样的孩子
//ChildOneClass header file
public ChildOneClass : public ParentClass{
public:
//Constructors and other functions
private:
//Other members
};
//Functions implemented in respective .cpp file
示例声明:
//Dynamically create one ChildOneClass object
ChildOneClass * c = new ChildOneClass();
//I know this is never done, but for example purposes i just did this
void * v = c;
我知道如果你有一个指针指向你可以做到的对象:
((ParentClass *) v)->someParentFunction();
或:
((ChildOneClass *) v)->someParentFunction();
但哪种方式是正确的?如果我将指向子类的指针转换为父类是否重要?很抱歉,如果这令人困惑,如果问题令人困惑,请给我一些反馈意见。我会尽力澄清
答案 0 :(得分:7)
对类指针唯一正确的void *转换是对传递给void *的原始类指针类型的强制转换。任何其他可能导致意外结果(例如:具有虚拟或多重继承)
答案 1 :(得分:3)
注意:此答案解决了原始问题的后续版本,该版本已被还原。有关问题原始和当前版本的答案,请参阅Dieter Lucking's answer。
如果要在可能具有包含该函数的派生类的类上调用someParentFunction()
,则需要将dynamic_cast
用于最基类该调用有效:
GrandParentClass *g = ...;
if (ParentClass* pc = dynamic_cast<ParentClass*>(g)) {
// ok, it's a ParentClass, this is safe
pc->someParentFunction();
}
else {
// not a ParentClass, do something else, log an error, throw, etc.
}
没有理由一直向下投放到ChildOneClass
,因为您会错过ParentClass
但不是ChildOneClass
的所有类型。这涵盖了所有有效的子集。请注意GrandParentClass
需要具有多态性才能实现此功能(例如GrandParentClass
具有virtual
成员函数。)
答案 2 :(得分:0)
当您创建多态层次结构时,您应该考虑 interfaces 。理想情况下,你永远不需要施放。但在某些情况下,这是必要的。
当你施放它时,它应该是你需要的特定界面。因此,如果您需要来处理派生类型的对象强制转换为派生类型。如果您需要来处理基类型转换为基类型的对象。
您的设计应该明确在系统中的哪个点处理接口。
如果你投了很多(甚至根本没有)它可能是设计不佳的症状。