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

时间:2015-05-05 20:36:20

标签: c++ pointers

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

但哪种方式是正确的?如果我将指向子类的指针转换为父类是否重要?很抱歉,如果这令人困惑,如果问题令人困惑,请给我一些反馈意见。我会尽力澄清

3 个答案:

答案 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 。理想情况下,你永远不需要施放。但在某些情况下,这是必要的。

当你施放它时,它应该是你需要的特定界面。因此,如果您需要来处理派生类型的对象强制转换为派生类型。如果您需要来处理基类型转换为基类型的对象。

您的设计应该明确在系统中的哪个点处理接口

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