已经有一段时间了,因为我不得不编写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)'"
}
我知道这应该很简单,但我不确定我做错了什么。
答案 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。
答案 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);