假定以下设置,其中我有一些抽象基类,它们定义了返回方法GetData
的方法,例如std::vector
和两个派生类,其中一个派生类的数据格式与由GetData
(以下为ProperSomeClass
返回),并且内部以某种奇怪的旧式C格式保存数据,即必须将该格式转换为std::vector
中的GetData
({ {1}})。
DerivedSomeClass
我正在寻找一种更好的方法来定义class ISomeClass
{
virtual std::vector<int> GetData() const = 0;
};
class ProperSomeClass : public ISomeClass
{
private:
std::vector<int> _data;
public:
std::vector<int> GetData() const { return _data; }
};
class DerivedSomeClass : public ISomeClass
{
private:
const void* _legacyFormat;
public:
std::vector<int> GetData() const
{
std::vector<int> temporary;
// some code that extracts relevant data from legacy format
return temporary;
}
};
(的返回值),使得GetData
不必复制其ProperSomeClass
成员。
我无法返回const引用,因为_data
随后将返回对已删除的本地对象的引用。
返回(智能)指针时,我必须考虑DerivedSomeClass::GetData
需要分配必须由调用方释放的内存,而由DerivedSomeClass::GetData
返回的指针所指向的内存一定不能被调用者释放了,我不知道该如何解决(除了使用ProperSomeClass::GetData
中的shared_ptr
需要保留一个副本,而不再使用它只是为了不删除其数据,在我看来这很丑陋。)
简而言之,理想情况下,我“只是”想要
ProperSomeClass
在不复制数据的情况下为我提供了const引用ProperSomeClass::GetData
构造向量并将其返回有没有办法做到这一点?或者,这是替代/更好的方式吗?
答案 0 :(得分:0)
您可以在ctor中初始化的std::vector
中添加DerivedSomeClass
,然后在GetData
中作为const ref返回,即:
class DerivedSomeClass : public ISomeClass
{
public:
DerivedSomeClass(void* legacyFormat):
_legacyFormat(legacyFormat),
_data(makeVectorFromLegacy(_legacyFormat))
{}
private:
const void* _legacyFormat;
const std::vector<int> _data;
public:
const std::vector<int>& GetData() const
{
return _data;
}
};
具有帮助函数,该函数可从const void*
指针创建该矢量,该方法与在DerivedSomeClass::GetData()
中提取数据的方式相同,只需要执行一次即可。
这与ProperSomeClass
稍有重复,这对您可能有好处,也可能没有好处,尽管它的优点是不会在每个派生类上强制使用std::vector
成员变量,从而可以将来可能不需要或不需要该成员std::vector
的实现。
答案 1 :(得分:0)
ISomeClass
的定义属性是使std::vector<int>
可用。由于ProperSomeClass
和DerivedSomeClass
都是从ISomeClass
派生的,因此它们都必须以相同的方式使该向量可用。例如,如果您希望通过const引用(对我来说这很合理)的方式,则需要将vector用作这两个类的成员。
请考虑在std::vector<int>
中拥有成员DerivedSomeClass
。如果要避免两次存储相同的数据(在向量和“旧格式”指针中),则可以在构造函数中而不是DerivedSomeClass::GetData
上“提取相关数据”,并摆脱{{1 }}成员。
如果_legacyFormat
绝对需要保留DerivedSomeClass
,我会认为此类和_legacyFormat
应该分开存放。
答案 2 :(得分:0)
这里的关键是您要从接口返回一些东西,具体取决于具体的实现,而该东西需要被调用方销毁(返回副本/唯一所有权)或不被销毁(返回对成员的引用)。调用者显然在编译时不知道这一点,因此我们需要一种机制来确定销毁对象的方式。您可以这样写,以便更明确地表达自己的意图,但我认为std::shared_ptr
可以达到目的:
#include <vector>
#include <memory>
using VectorPtr = std::shared_ptr<std::vector<int>>;
class ISomeClass
{
virtual VectorPtr GetData() const = 0;
};
class ProperSomeClass : public ISomeClass
{
private:
VectorPtr _data;
public:
VectorPtr GetData() const { return _data; }
};
class DerivedSomeClass : public ISomeClass
{
private:
const void* _legacyFormat;
public:
VectorPtr GetData() const
{
VectorPtr temporary;
// some code that extracts relevant data from legacy format
return temporary;
}
};