Tec*_*ton 6 c++ api smart-pointers
我即将设计一个存在两个类的API:数据/计算类和此类的容器.然而,容器不仅仅是一个愚蠢的容器,而且还包含整个集合的信息,这超出了可以用迭代器实现的通常的东西.
因此,容器基本上包装了一个std::vector,添加了一些预先计算的属性,实用程序函数等.容器类的API也应该包含的是
我不只是想向std::vector公众开放,因为向容器添加新的数据/计算类会导致重新计算集合类的许多属性.我想,但是,提供访问方法等同于STL容器的存取方法at()和operator [].
最初,我添加了该类型的私有属性std::vector<std::unique_ptr<DataClass>>.addDataObject(DataObject *d)存在一种方法,它将对象包装在一起unique_ptr并更新统计信息.
然而,问题在于访问器方法:它们的返回类型是什么?
std::unique_ptr<DataClass> &似乎不是一个干净的API设计:API的用户不需要知道我使用智能指针.(另见Herb Sutter关于C++ 11的演讲)DataClass *&是不可能的,尤其不适用operator [],因为我只能std::unique_ptr使用智能指针的get()方法访问一个原始指针,这不会给我一个参考.DataClass &似乎没有意义,特别是当我存储指针(堆与堆栈分配)时.DataClass *会违反最少惊喜的princpile,因为如果一个方法是在STL容器访问器方法的意义上命名的,那么人们会期望它返回一个引用,特别是对于operator [].作为一个例子,这将是一个简化的例子:
class DataClass
{
Container *m_parent;
/* ... other member attributes/parameters ... */
public:
/* A method that calculates something based on the attributes: */
double someComplicatedCalculation(const double &input);
};
class Container
{
std::vector<std::unique_ptr<DataClass>> m_collection;
/* more attributes: maintenance info, precomputed values, etc. */
public:
void addDataObject(DataClass *d);
/* What would the right return type be? */
DataClass *&at(const int &index);
const DataClass *&at(const int &index) const;
DataClass *&operator [](const int &index);
const DataClass *&operator [](const int &index) const;
};
Run Code Online (Sandbox Code Playgroud)
当您不了解所有细节时,这总是很困难,但我认为:
- 简单地返回
std::unique_ptr<DataClass> &似乎不是一个干净的 API 设计:API 的用户不需要知道我使用智能指针。(另请参阅 Herb Sutter 关于 C++11 的演示)
绝对是的。
- 返回
DataClass *&是不可能的,尤其是 foroperator [],因为我只能std::unique_ptr使用智能指针的get()方法访问 an 的原始指针,这不会给我一个引用。
的确。
- 返回
DataClass &似乎没有意义,特别是当我存储指针(堆与堆栈分配)时。
这确实有道理。我认为一开始就存储指针可能没有意义。无论如何, Astd::vector将所有内容存储在堆上,因此如果这是使用指针的原因,则它不适用。
- 返回
DataClass *会违反最小意外原则,因为如果一个方法是在 STL 容器访问器方法的意义上命名的,那么人们会期望它返回一个引用,特别是对于operator [].
的确。
我想说你应该回来DataClass&。也许你不应该在你的中使用指针std::vector,但如果你必须使用它们,你可以让你的访问器像:
DataClass& operator[](std::size_t index)
{
return *m_collection[index];
}
Run Code Online (Sandbox Code Playgroud)
但最好不要使用指针:
class Container
{
std::vector<DataClass> m_collection;
DataClass& operator[](std::size_t index)
{
return m_collection[index];
}
// ...
};
Run Code Online (Sandbox Code Playgroud)