简体   繁体   English

C ++从派生类和基类来回转换

[英]C++ converting back and forth from derived and base classes

I was wondering if there is a way in C++ to accomplish the following: 我想知道C ++中是否有一种方法可以完成以下任务:

I have a base class called ResultBase and two class that are Derived from it, Variable and Expression . 我有一个名为ResultBase的基类,还有两个派生自该类的类, VariableExpression I have a few methods that do work on vector<ResultBase> . 我有一些对vector<ResultBase>起作用的方法。 I want to be able to pass in vectors of Variable and Expression into these methods. 我希望能够将VariableExpression向量传递到这些方法中。 I can achieve this by creating a vector<ResultBase> and using static_cast to fill it with the members from my vector of Variable/Expression. 我可以通过创建vector<ResultBase>并使用static_cast填充来自我的Variable / Expression向量的成员来实现。 However, once the vector has run through the methods, I want to be able to get it back as the vector of Result/Expression. 但是,一旦向量通过方法运行,我希望能够将其作为Result / Expression的向量取回。 I'll know for sure which one I want back. 我肯定知道我要回哪一个。 static_cast won't work here as there isn't a method to reconstruct a Variable/Expression from a ResultBase , and more importantly I wouldn't have the original properties of the Variables/Expressions static_cast在这里不起作用,因为没有一种方法可以从ResultBase重构变量/表达式,更重要的是,我没有变量/表达式的原始属性

The methods modify some of the properties of the ResultBase and I need those changes to be reflected in the original vectors. 这些方法修改了ResultBase某些属性,我需要将这些更改反映到原始向量中。 (ie ResultBase has a property called IsLive , and one of the methods will modify this property. I want this IsLive value to be reflected in the derived class used to create the ResultBase (即ResultBase具有一个称为IsLive的属性,其中一种方法将修改此属性。我希望将此IsLive值反映在用于创建ResultBase的派生类中。

Whats the easiest way to accomplish this? 最简单的方法是什么?

vector<ResultBase *> should fix your slicing problem - a vector<ResultBase> will never contain classes derived from ResultBase , but rather copies that "slice off" eg Expression by copying the ResultBase part of it. vector<ResultBase *>应该解决您的切片问题vector<ResultBase>绝不会包含从ResultBase派生的类,而是通过复制ResultBase部分来复制“切片”(例如Expression

See What is object slicing? 请参阅什么是对象切片? for a detailed explanation of slicing. 有关切片的详细说明。

One possibility is to change your functions that do work on vector<ResultBase> into function templates that do work on vector<T> , with T a template parameter. 一种可能是将对vector<ResultBase>起作用的函数vector<ResultBase>为对vector<T>起作用的函数模板,其中T为模板参数。 To be even more generic, perhaps the functions can operate on a pair of iterators instead of a particular container type. 为了更加通用,这些函数可以在一对迭代器上运行,而不是在特定的容器类型上运行。

You can then call them with a vector<Variable> or vector<Expression> instead of a vector<ResultBase> , as long as Variable and Expression are both proper substitutes for ResultBase , as a derived class should be. 然后,您可以使用vector<Variable>vector<Expression>代替vector<ResultBase> vector<Expression>来调用它们,只要VariableExpression都是ResultBase适当替代ResultBase ,就应该派生类。

Alternatively as Erik says you can use pointers to get polymorphic behavior with containers. 就像Erik所说的那样,您可以使用指针来获得容器的多态行为。 For ease of memory management, a vector of smart pointers or a Boost ptr_vector is usually preferred to a vector of raw pointers. 为了简化内存管理,通常首选使用智能指针向量或Boost ptr_vector不是原始指针向量。

There's no way to convert an instance of a derived class to base and then back to derived, while preserving its original value, for pretty much the same reason that it's not possible to convert from int to char and then back, preserving the original value. 由于几乎相同的原因,无法将int转换为char然后再返回,以保留原始值,因此无法将派生类的实例转换为基然后再返回到deriv,同时保留其原始值。 If all else fails, you could perhaps bodge something together where you use the modified ResultBase objects to somehow update the original Variable or Expression objects with any changes made by the functions. 如果所有其他方法均失败,则可能会合并在一起,在其中使用修改后的ResultBase对象以某种方式通过函数所做的任何更改来更新原始的VariableExpression对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM