C++ 如何将父类转换为子类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4089726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I cast a parent class as the child class
提问by Mykroft
It's been a while since I have had to write C++ code and I'm feeling kind of stupid. I've written code that is similar to, but is not exactly, the code below:
自从我不得不编写 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)'"
}
I know this is supposed to be simple but I'm not sure what I'm doing wrong.
我知道这应该很简单,但我不确定我做错了什么。
采纳答案by fredoverflow
A Parent
object returned by value cannotpossibly contain any Child
information. You have to work with pointers, preferably smart pointers, so you don't have to clean up after yourself:
阿Parent
通过值返回的对象不能可能包含任何Child
信息。你必须使用指针,最好是智能指针,所以你不必自己清理:
#include <memory>
class Factory
{
// ...
public:
static std::unique_ptr<Parent> GetThing()
{
return std::make_unique<Child>();
}
};
int main()
{
std::unique_ptr<Parent> p = Factory::GetThing();
if (Child* c = dynamic_cast<Child*>(p.get()))
{
// do Child specific stuff
}
}
回答by Steve Jessop
You can't, really. Your factory has returned a Parent
object, which was constructed from the Child
object c
[*]. The Child part of it has already been sliced away, as it's returned to the main
function. There's no way to recover it.
你不能,真的。您的工厂返回了一个Parent
对象,该对象是从Child
对象c
[*]构造的。当它返回给main
函数时,它的 Child 部分已经被切掉了。没有办法恢复它。
Perhaps you want to use pointers?
也许您想使用指针?
[*] Except that, Child c();
declares a function, it doesn't define an object. But this isn't your real code, and I guess your real class has constructor parameters.
[*] 除了Child c();
声明一个函数,它没有定义一个对象。但这不是你真正的代码,我猜你真正的类有构造函数参数。
回答by parasrish
Refer to the code snippet below:
参考下面的代码片段:
Child* c = dynamic_cast<Child*>(parentObject);
where, parentObject
is of type Parent*
其中,parentObject
是类型Parent*
Ensure, that the "parentObject" is actually of "Child" type, otherwise undefined-behavior.
确保“parentObject”实际上是“Child”类型,否则为未定义行为。
Refer for More Info
请参阅更多信息
回答by Jean-Marc Valin
I think the problem isn't with how your trying to do the cast, but with why you want to cast in the first place. The code makes no sense -- even if it was syntaxically valid. You;re trying to cast a "fruit" into an "apple" in a context where it's easy to prove that you don't actually have an apple. Dynamic casts and similar are only useful when you have a pointer to a "fruit" that you have reasons to thing is also an "apple".
我认为问题不在于您如何尝试进行演员表,而在于您首先为什么要进行演员表。代码毫无意义——即使它在语法上是有效的。在很容易证明您实际上没有苹果的情况下,您正试图将“水果”扔进“苹果”中。只有当您有一个指向“水果”的指针并且您有理由认为事物也是“苹果”时,动态转换和类似方法才有用。
回答by CashCow
You probably don't want to be casting here at all. If Parent has any abstract methods you just call them and the derived class will automatically handle them correctly.
你可能根本不想在这里选角。如果 Parent 有任何抽象方法,您只需调用它们,派生类将自动正确处理它们。
There are times where you link relatively unrelated items together just so you can store them in a collection, either variant types or situations where different state leads to unrelated objects which are handled differently, and on those occasions you might want to cast.
有时您将相对不相关的项目链接在一起,以便您可以将它们存储在一个集合中,无论是变体类型还是不同状态导致以不同方式处理的不相关对象的情况,并且在这些情况下您可能想要强制转换。
I am quite surprised, by the way, that you didn't get a compiler error on GetThing() because you have declared c as a function so you are not returning a Parent.
顺便说一下,我很惊讶您没有在 GetThing() 上收到编译器错误,因为您已将 c 声明为函数,因此您没有返回父级。
In addition, by the way, if you copy by value you will "slice" thus:
此外,顺便说一句,如果您按值复制,您将因此“切片”:
Child c;
Parent p(c);
Child & c2 = dynamic_cast< Child& >(p); // throws bad_cast
回答by AnT
You cannot cast an object of parent class to child class type. An object of parent class is... well, an object of parent class. Child class extendsparent class, meaning that an object of parent class is generally "smaller" than an object of child class. For this reason casting (or reinterpreting) parent class as child class makes no sense whatsoever.
您不能将父类的对象强制转换为子类类型。父类的对象是……嗯,父类的对象。子类扩展父类,这意味着父类的对象通常比子类的对象“小”。出于这个原因,将(或重新解释)父类转换为子类毫无意义。
Explain what is it you are trying to do. Without an explanation, your question simply makes no sense.
解释你想要做什么。没有解释,你的问题根本没有意义。
回答by Andres Camilo Sierra Hormiga
You can cast using Single Argument Constructor: i.e. (A parent works, A child Studies) as follows:
您可以使用 Single Argument Constructor 进行转换:即(A parent works,A child Studies)如下:
#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;
}
you pass an child class address as parent's constructor parameter and you can use a child obj to do parent's stuff
您将子类地址作为父类的构造函数参数传递,您可以使用子 obj 来执行父类的操作
回答by jhabbott
You cannot cast the actual objects, but you can cast pointers to the objects.
您不能转换实际对象,但可以转换指向对象的指针。
To cast pointers use code like this:
要转换指针,请使用如下代码:
Child* c = reinterpret_cast<Child*>(p);