c++将基类强制转换为派生类混乱
如果我要创建一个名为 base
的基类和名为 衍生_1
、衍生_2
等的派生类...我使用基类,然后当我检索一个元素并尝试使用它时,我会发现 C++ 认为它的类型是基类的类型,可能是因为我从基类的 std::vector
检索它。当我想使用仅存在于特定派生类的功能时,这是一个问题,当我将其放入向量时,我知道该对象的类型。
所以我将元素转换为它应该的类型,但发现这是行不通的。
(derived_3)obj_to_be_fixed;
并记住这是一个指针的事情。经过一些调整后,现在可以了。
*((derived_3*)&obj_to_be_fixed);
这是正确的还是有例如 abc_cast() 函数可以减少混乱?
编辑:
我不得不将其扩展为另一个问题,完整的解决方案显示在那里。 stackoverflow.com ... 为什么-the-polymorphic-types-error-和清理问题
If I were to create a base class called base
and derived classes called derived_1
, derived_2
etc... I use a collection of instances of the base class, then when I retrieved an element and tried to use it I would find that C++ thinks it's type is that of the base class, probably because I retrieved it from a std::vector
of base. Which is a problem when I want to use features that only exist for the specific derived class who's type I knew this object was when I put it into the vector.
So I cast the element into the type it is supposed to be and found this wouldn't work.
(derived_3)obj_to_be_fixed;
And remembered that it's a pointer thing. After some tweaking this now worked.
*((derived_3*)&obj_to_be_fixed);
Is this right or is there for example an abc_cast()
function that does it with less mess?
edit:
I had to expand this into another question, the full solutions are shown there. stackoverflow.com ... why-the-polymorphic-types-error-and-cleanup-question
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果将对象存储在
std::vector
中,则根本无法返回派生类。这是因为派生部分在将其存储在基类的实例中时已被切片(毕竟您的向量包含数据的副本,因此它很乐意仅复制对象的基本部分),从而使存储的对象成为基类,而不是用作基类的派生类。如果您想在向量中存储多态对象,请使其成为 std::vector
dynamic_cast<衍生_3*>
将其转换为正确的类型(或static_cast
,如果它的性能敏感并且您有足够的信心尝试转换为正确的类型(在这种情况下可怕如果你错了,事情就会发生,所以要小心))。If you store your objects in a
std::vector<base>
there is simply no way to go back to the derived class. This is because the derived part has been sliced of when storing it in an instance of base class (afterall your vector contains copies of your data, so it happily copies only the base part of your objectes), making the stored object a true instance of base class, instead of a derived class used as a base class.If you want to store polymorphic objects in the vector make it a
std::vector<base*>
(or some kind of smartpointer to base, but not base itself) and usedynamic_cast<derived_3*>
to cast it to the correct type (orstatic_cast
, if its performance sensitive and you are confident enough that you are trying to cast to the correct type (in that case horrible things will happen if you are wrong, so beware)).如果您使用的是
base
的向量
,那么您的所有实例都是base
实例,而不是派生实例。如果您尝试插入派生实例,该对象将被切片。插入到
向量
中总是涉及复制,并且目标类型由向量所保存的对象的类型确定。向量
不能容纳不同类型的对象。If you are using a
vector
ofbase
then all your instances arebase
instances and not derived instances.If you try to insert a derived instance, the object will be sliced. Inserting into a
vector
always involves a copy and the target type is determined by the type of the object that the vector holds. Avector
cannot hold objects of different types.大多数时候您不需要这样做。精心设计的类层次结构可以通过多态性(即虚函数)来处理这个问题。
如果您确实需要强制转换为派生类型,请使用
dynamic_cast
运算符。Most of the time you shall not need to do this. A carefully designed class hierarchy can handle this by polymorphism (i.e. virtual functions).
If you really need to cast to the derived type, use
dynamic_cast
operator.你想要做的事情根本不可能实现。如果存储在容器中的对象的类型为
base
,那么它们就是base
,句点。它们不是派生
对象,它们永远不会成为派生
对象,并且无论您做什么,它们都不能用作派生
对象。您通过指针进行的转换只不过是一种将
base
对象占用的内存重新解释为衍生
对象的黑客行为。这完全没有意义,只能偶然“起作用”。What you are trying to do is not even remotely possible. If the objects stored in your container have type
base
, then they arebase
, period. They are notderived
objects, they will never becomederived
objects and they cannot be used asderived
objects regardless of what you do.Your cast through pointers is nothing than just a hack that reinterprets memory occupied by
base
object asderived
object. This is totally meaningless and can only "work" by accident.