如何将父类强制转换为子类

时间:2010-11-03 17:19:52

标签: c++

已经有一段时间了,因为我不得不编写C ++代码而且我感觉有点愚蠢。我编写的代码类似于但不完全,代码如下:

class Parent
{
    ...
};

class Child : public Parent
{
    ...
};

class Factory
{
    static Parent GetThing() { Child c; return c; }
};

int main()
{
    Parent p = Factory::GetThing();
    Child c1 = p; // Fails with "Cannot convert 'Parent' to 'Child'"
    Child c2 = (Child)p; // Fails with "Could not find a match for 'TCardReadMessage::TCardReadMessage(TCageMessage)'"
}

我知道这应该很简单,但我不确定我做错了什么。

8 个答案:

答案 0 :(得分:22)

返回的Parent对象无法可能包含任何Child信息。你必须使用指针,最好是智能指针,所以你不必自己清理:

#include <memory>

class Factory
{
    // ...

public:

    static std::auto_ptr<Parent> GetThing()
    {
        return std::auto_ptr<Parent>(new Child());
    }
};

int main()
{
    std::auto_ptr<Parent> p = Factory::GetThing();
    if (Child* c = dynamic_cast<Child*>(p.get()))
    {
        // do Child specific stuff
    }
}

答案 1 :(得分:3)

你不能,真的。您的工厂已返回Parent 对象,该对象是从Child对象c [*]构建的。它的Child部分已被切掉,因为它已返回main函数。没有办法恢复它。

也许您想使用指针?

[*]除此之外,Child c();声明了一个函数,它没有定义一个对象。但这不是你真正的代码,我猜你真正的类有构造函数参数。

答案 2 :(得分:2)

我认为问题不在于你是如何尝试演员,而是为什么你想要首先演员。代码没有意义 - 即使它在语法上有效。你;在一个容易证明你实际上没有苹果的环境中,试图将“水果”投入“苹果”。动态强制转换和类似功能仅在你有一个指向“水果”的指针时才有用,你有理由认为它也是一个“苹果”。

答案 3 :(得分:0)

您不能将父类的对象强制转换为子类类型。父类的对象是......嗯,父类的对象。子类扩展父类,这意味着父类的对象通常比子类的对象“更小”。因此,将父类作为子类进行(或重新解释)是没有任何意义的。

解释你要做的是什么。没有解释,你的问题根本就没有意义。

答案 4 :(得分:0)

你可能根本不想在这里施展。如果Parent有任何抽象方法,您只需调用它们,派生类将自动正确处理它们。

有时您将相对不相关的项目链接在一起,这样您就可以将它们存储在一个集合中,无论是变体类型还是不同状态导致不同处理的不相关对象的情况,以及您可能想要投射的那些情况。

顺便说一句,我很惊讶你没有在GetThing()上得到编译器错误,因为你已经将c声明为函数,所以你没有返回Parent。

此外,顺便说一下,如果按值复制,你将“切片”:

Child c;
Parent p(c);
Child & c2 = dynamic_cast< Child& >(p); // throws bad_cast

答案 5 :(得分:0)

请参阅下面的代码段:

Child* c = dynamic_cast<Child*>(parentObject);

其中,parentObject的类型为Parent*

确保“parentObject”实际上是“Child”类型,否则为undefined-behavior。

参考More Info

答案 6 :(得分:0)

您可以使用Single Argument Constructor进行强制转换: 即(父母的作品,儿童研究)如下:

#include <iostream>
using std::cout;

class Parent
{
    public:
    void goToWork()
    {
        cout<<"working\n";  // only parents work
    }
};

class Child : public Parent
{
    public:
    Child(const Parent& parentAddr){}
    void goToSchool()
    {
        cout<<"studying\n";   // only children studies
    }
};

int main(void)
{
    Child child(*(new Parent()));

    // here's a child working
    child.goToWork();
    return 0;
}

您将子类地址作为父级的构造函数参数传递,您可以使用子obj来执行父级的东西

答案 7 :(得分:-1)

您无法转换实际对象,但可以将指针转换为对象。

要转换指针,请使用以下代码:

Child* c = reinterpret_cast<Child*>(p);