在C++对象中:我应该使用父类强制转换指针,还是应该使用实际类本身进行强制转换

In C++ objects: Should I be casting pointers with the parent class or should I be casting with the actual class itself

本文关键字:转换 指针 对象 C++ 我应该 父类      更新时间:2023-10-16

我在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();

但是哪种方式是正确的方法呢?如果我将指向子类的指针转换为父类,这有关系吗?抱歉,如果这令人困惑,如果问题令人困惑,请给我一些反馈。我会尽力澄清

将 void* 强制转换为类指针的唯一正确转换是传递给 void* 的原始类指针类型的强制转换。其他任何事情都可能导致意外结果(例如:具有虚拟或多重继承)

注意:此答案解决了原始问题的后续修订版,该修订版已被还原。有关该问题的原始和当前修订版的答案,请参阅Dieter Lucking的回答。

如果要对可能具有包含该函数的派生类的类调用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成员函数)。

当你创建多态层次结构时,你应该从接口的角度来考虑。理想情况下,您永远不需要投射。但是在某些情况下,这是必要的。

当您将其转换为所需的特定接口时。因此,如果需要处理派生类型的对象,则强制转换为派生类型。如果需要处理转换为基类型的基类型的对象。

您的设计应该清楚地表明在系统中的哪个点正在处理哪个接口

如果你铸造了很多(甚至根本没有),这可能是设计不佳的症状。