为什么在所有情况下都允许使用裸指针shared_ptr构造? [英] Why is raw pointer to shared_ptr construction allowed in all cases?

查看:201
本文介绍了为什么在所有情况下都允许使用裸指针shared_ptr构造?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在阅读十大愚蠢的错误,避免与C ++ 11智能指针
Number#5:


错误#5:没有将对象(原始指针)指定为shared_ptr为$ b $




  int main()
{
飞机* myAircraft =新飞机(F-16);
shared_ptr< aircraft> pAircraft(myAircraft);
...
shared_ptr< aircraft> p2(myAircraft);
//将执行双删除并可能会崩溃
}

建议如下:


使用 make_shared 并立即用
it构造指针。


好,毫无疑问和建议。但我有一个关于 shared_ptr 设计的问题。这是一个很容易犯的错误,并且 shared_ptr 的整个安全设计可能被非常容易的错误抛弃。



现在的问题是,可以很容易地用 shared_ptr 的替代设计来修复,其中从raw指针的唯一构造函数是从r值引用?

 模板< class T& 
struct shared_ptr {
shared_ptr(T *& t){...基本上当前实现...}
shared_ptr(T * t)= delete; //这是...
shared_ptr(T * const& t)= delete; // ...说明点。
shared_ptr(T *& t)= delete;
...
};

这样, shared_ptr new 或一些工厂函数的结果。



这是C ++语言的开发库?
如果这最可能是滥用,从原始指针(l值)引用构造函数的意义是什么? >

这是历史性的意外吗? (例如,在引入r值引用之前建议使用shared_ptr等)向后兼容性?



(当然可以说 std :: shared_ptr< >

p>我缺少了什么?

解决方案

指针很容易复制。即使你限制r值引用,你也可以轻松地进行复制(例如当你将指针作为函数参数传递时),这将使安全设置无效。此外,你会遇到问题的模板,你可以很容易地有 T * const T *& 并且你得到类型不匹配。



所以你建议创建更多的限制没有重大的安全收益,这可能是为什么它不是在标准开始。 p>

make_shared 的意思是原子化一个共享指针的构造。假设你有 f(shared_ptr< int>(new int(5)),throw_some_exception())。参数调用的顺序不受标准保证。编译器允许创建一个新的int,运行 throw_some_exception 然后构造shared_ptr这意味着你可以泄漏int(如果 throw_some_exception 实际抛出异常)。 make_shared 只是创建对象和共享指针在内部,这不允许编译器更改顺序,因此它变得安全。


I was reading Top 10 dumb mistakes to avoid with C++11 smart pointer. Number #5 reads:

Mistake # 5 : Not assigning an object(raw pointer) to a shared_ptr as soon as it is created !

int main()
{
    Aircraft* myAircraft = new Aircraft("F-16"); 
    shared_ptr<aircraft> pAircraft(myAircraft);
    ...
    shared_ptr<aircraft> p2(myAircraft); 
    // will do a double delete and possibly crash
}

and the recommendation is something like:

Use make_shared or new and immediately construct the pointer with it.

Ok, no doubt about it the problem and the recommendation. However I have a question about the design of shared_ptr. This is a very easy mistake to make and the whole "safe" design of shared_ptr could be thrown away by very easy missuses.

Now the question is, could this be easily been fixed with an alternative design of shared_ptr in which the only constructor from raw pointer would be that from a r-value reference?

template<class T>
struct shared_ptr{
    shared_ptr(T*&& t){...basically current implementation...}
    shared_ptr(T* t) = delete; // this is to...
    shared_ptr(T* const& t) = delete; // ... illustrate the point.
    shared_ptr(T*& t) = delete;
    ...
};

In this way shared_ptr could be only initialized from the result of new or some factory function.

Is this an underexploitation of the C++ language in the library? or What is the point of having a constructor from raw pointer (l-value) reference if this is going to be most likely a misuse?

Is this a historical accident? (e.g. shared_ptr was proposed before r-value references were introduced, etc) Backwards compatibility?

(Of course one could say std::shared_ptr<type>(std::move(ptr)); that that is easier to catch and also a work around if this is really necessary.)

Am I missing something?

解决方案

Pointers are very easy to copy. Even if you restrict to r-value reference you can sill easily make copies (like when you pass a pointer as a function parameter) which will invalidate the safety setup. Moreover you will run into problems in templates where you can easily have T* const or T*& as a type and you get type mismatches.

So you are proposing to create more restrictions without significant safety gains, which is likely why it was not in the standard to begin with.

The point of make_shared is to atomize the construction of a shared pointer. Say you have f(shared_ptr<int>(new int(5)), throw_some_exception()). The order of parameter invokation is not guaranteed by the standard. The compiler is allowed to create a new int, run throw_some_exception and then construct the shared_ptr which means that you could leak the int (if throw_some_exception actually throws an exception). make_shared just creates the object and the shared pointer inside itself, which doesn't allow the compiler to change the order, so it becomes safe.

这篇关于为什么在所有情况下都允许使用裸指针shared_ptr构造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆