在C ++中获取所有权和释放对象的语法准则

时间:2011-11-03 09:26:58

标签: c++ ownership

我想知道 - 是否有关于C ++(非)成员函数语法的指导,这使我能够理解(如果可能的话,没有注释)其参数和返回值的所有权策略。根据所有权,我的意思是,所有者负责销毁拥有的对象。

我区分了以下有关参数的规则:

  • 取得所有权
  • 不取得所有权
  • 份额

和关于返回值:

  • 发布('按值返回'在此组中)
  • 不发布
  • 份额

例如,通过引用传递对象不会拥有它的所有权:

void func(object & obj) { ... }

此类指南可能使用标准结构,如unique_ptr,shared_ptr等。如果没有这样的指导原则,那么也欢迎可能存在语法误解的示例。

3 个答案:

答案 0 :(得分:8)

我看不出为什么使用智能指针是不够的。我想不出任何我不会归类为code smell的东西。在原始指针上使用智能指针使得所有权和响应能力非常清晰:

  • auto_ptr / unique_ptr - 单一所有者,所有权已转让
  • shared_ptr - 可以转让多个所有者,所有权
  • scoped_ptr - 单一所有者,所有权无法转让
  • weak_ptr - 观察员(但可以shared_ptr创建weak_ptr

我认为这些足以清楚地表明责任,例如

void func(std::auto_ptr<Class> input) {...} // func() takes ownership of input
void func(std::shared_ptr<Class> input) {...} // func() and caller share ownership
std::auto_ptr<Class> func() {...} // caller takes ownership of returned value
std::shared_ptr<Class> func() {...} // func() and caller shares ownership of returned object
std::weak_ptr<Class> func() {...} // func() owns created object, but caller may observe it

正如您所提到的,从这个意义上来说,参考文献也很棒。请注意,如果需要使用某种自定义机制释放指针,shared_ptrunique_ptr支持自定义删除。 auto_ptr没有此功能。

请注意!如果您使用的是C ++ pre-11,则必须使用boost::shared_ptrboost:weak_ptr

答案 1 :(得分:0)

我只是在需要的地方使用这种语法:

示例构造函数声明:

t_array(const t_ownership_policy::t_take& policy, THESpecialType* const arg);

在呼叫现场使用:

t_array array(t_ownership_policy::Take, THESpecialTypeCreate(...));

其中t_ownership_policy::t_take只是一个虚拟重载消歧器类型名称。

在此系统中,有多个策略,每个策略都有不同的类型。我赞成每个策略的唯一类型,因为类型化枚举(例如)不容易支持初始化,并且将不受支持的策略传递给函数或构造函数太容易了。 “多态”策略可以减少符号数量,但这很痛苦,因为它会将错误检测推送到运行时。

'返回':

void func(t_container<t_type>& outValue);

其中t_container是您选择的指针容器类型。然后容器类型已经实现了必要的样板。这个容器可能类似于shared_ptr,或者你写过的一些专业化。

对于更复杂的类型,我经常使用这样的语法:

void func(t_special_container& outValue) {
  ...
  outValue.take(ptr);
  - or -
  outValue.copy(ptr);

答案 2 :(得分:0)

如果我了解你,那么Boost call_traits可能就是你想要的:

示例(从文档中复制):

template <class T>
struct contained
{
   // define our typedefs first, arrays are stored by value
   // so value_type is not the same as result_type:
   typedef typename boost::call_traits<T>::param_type       param_type;
   typedef typename boost::call_traits<T>::reference        reference;
   typedef typename boost::call_traits<T>::const_reference  const_reference;
   typedef T                                                value_type;
   typedef typename boost::call_traits<T>::value_type       result_type;

   // stored value:
   value_type v_;

   // constructors:
   contained() {}
   contained(param_type p) : v_(p){}
   // return byval:
   result_type value() { return v_; }
   // return by_ref:
   reference get() { return v_; }
   const_reference const_get()const { return v_; }
   // pass value:
   void call(param_type p){}

};

param_typereference_typereturn_type更清楚地表明其含义。