具有std :: unique_ptr

时间:2015-04-26 17:06:49

标签: c++ api smart-pointers

我即将设计一个存在两个类的API:数据/计算类和此类的容器。然而,容器不仅仅是一个愚蠢的容器,而且还包含整个集合的信息,这超出了通常可以用迭代器实现的东西。

因此,容器基本上包装了std::vector,添加了一些预先计算的属性,实用程序函数等。容器类的API也应该包含什么

  1. 添加data / calc类实例的方法
  2. 存取方法。
  3. 我不只是想向公众打开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()的原始指针1}}方法,它没有给我一个参考。
    • 返回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;
    };
    

2 个答案:

答案 0 :(得分:2)

  

返回DataClass &似乎没有意义,特别是当我存储指针(堆与堆栈分配)时。

我不同意。这就是所有标准容器的回报。除非您使用unique_ptr这一事实应该对用户可见(并且我假设它不应该是这样),那么最不惊讶的路径就是像标准库那样做:返回对象的左值引用。

此外,返回引用可以明确所有权。如果要返回指针,则必须指明用户不得删除它。

答案 1 :(得分:1)

当你不知道所有细节时总是很难,但这就是我的想法:

  
      
  • 简单地返回std::unique_ptr<DataClass> &似乎不是一个干净的API设计:API的用户不需要知道我使用   智能指针。 (另见Herb Sutter关于C ++ 11的演讲)
  •   

肯定是的。

  
      
  • 无法返回DataClass *&,尤其是operator [],因为我只能访问原始指针   std::unique_ptr使用智能指针的get()方法   不要给我一个参考。
  •   

确实

  
      
  • 返回DataClass &似乎没有意义,特别是当我存储指针(堆与堆栈分配)时。
  •   

这确实有道理。我认为可能没有意义的是存储指针开头。无论如何,std::vector都会将所有内容存储在堆上,因此,如果这是使用指针的原因,则不适用。

  
      
  • 返回DataClass *会违反最少惊喜的princpile,因为如果一个方法是在STL意义上命名的   容器访问器方法,人们会期望它返回一个引用,   特别是operator []
  •   

确实

我会说你应该回归DataClass&。可能你不应该在你的std::vector中使用指针,但是如果你必须使用它们,你可以使你的访问者像:

DataClass& operator[](std::size_t index)
{
    return *m_collection[index];
}

但更好的方法是不使用指针:

class Container
{
     std::vector<DataClass> m_collection;

    DataClass& operator[](std::size_t index)
    {
        return m_collection[index];
    }

    // ...
};