c++中获取所有权和释放对象的语法指南
Syntax guidelines for taking ownership and releasing objects in C++
我想知道-是否有任何关于c++(非)成员函数的语法指南,使我能够理解(如果可能的话,没有注释)其参数和返回值的所有权策略。我所说的所有权是指所有者对其拥有的对象的销毁负责。
我区分以下关于参数的规则:
- 不占有所有权
和关于返回值:
- release ('return by value'在该组中)
- 不要发布
例如,通过引用传递对象并不获取它的所有权:
void func(object & obj) { ... }
这样的指南可以使用unique_ptr、shared_ptr等标准结构。如果没有这样的指导方针,那么也欢迎提供可能的语法误解示例。
我不明白为什么使用智能指针不够。我想不出还有什么东西不属于代码气味。使用智能指针而不是原始指针使所有权和责任非常清晰:
-
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_ptr
和unique_ptr
支持自定义删除器。auto_ptr
没有此功能。
注意!如果您使用的是c++ 11之前版本,则必须使用boost::shared_ptr
和boost:weak_ptr
。
如果我理解你,那么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_type
, reference_type
和return_type
更清楚地表明意思
我只是在需要的地方对参数使用这种语法:
示例构造函数声明:
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
只是一个虚拟的重载消歧器typename。
在这个系统中,有多个策略,每个策略都有单独的类型。我喜欢每个策略唯一的类型,因为类型化枚举(例如)不容易支持初始化,而且很容易将不受支持的策略传递给函数或构造函数。"多态"策略可以减少符号计数,但这是一个痛苦,因为它将错误检测推到运行时。
为"返回":void func(t_container<t_type>& outValue);
其中t_container
为您选择的指针容器类型。那么容器类型已经实现了必要的样板。这个容器可以是shared_ptr
之类的东西,或者是您编写的某种专门化。
对于更复杂的类型,我经常使用这样的语法:
void func(t_special_container& outValue) {
...
outValue.take(ptr);
- or -
outValue.copy(ptr);
- 实例化对象并调用方法,使用单行语法在 C# 或 C++ 中返回值?
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 访问对象的取消引用值的语法
- 模板堆栈对象的数组;语法
- C 中的对象依赖性.什么是班级组成的语法
- 未知的 C++ 对象实例化语法
- (C++)用于实例化新对象并将其分配给指向相同对象类型的指针的 2D 向量的语法
- C++构造函数中的语法错误 - arugment 是对另一个类中的对象的引用
- 是否可以通过从lambda的引用中返回T型对象,而无需使用尾随返回类型语法
- 对象构造语法
- 使用自定义对象的地图使用MAP?可能是语法问题
- 无法弄清楚将多个对象函数作为单独的线程调用的语法
- 使用大括号初始化C++对象(语法)
- C++中生成对象的语法差异
- 使用std::sort与自定义排序对象和数据类型模板-寻找正确的语法
- 比较类语法帮助中的对象;
- 我们什么时候应该使用括号 ( ) 与初始值设定项 { } 语法来初始化 C++11 中的对象
- 语法错误:使用指向对象的指针调用成员函数指针
- C++中的对象初始化语法
- std::array 作为字段的语法是什么,里面的对象必须使用接受参数的 ctor 构造