C++ shared_ptr 空指针和赋值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10266272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:49:44  来源:igfitidea点击:

shared_ptr null pointer and assignment

c++pointersnullshared-ptr

提问by Michael Ferris

I want to use shared_ptr just like I'd use an actual pointer. I wanted to be able to do things like

我想使用 shared_ptr 就像使用实际指针一样。我希望能够做这样的事情

shared_ptr<int> a;
a = new int(5);
a = 0;
shared_ptr<int> foo()
    return 0;

but it is not implemented by default.

但它不是默认实现的。

I changed the source code of the shared_ptr of the boost library by adding

我通过添加更改了boost库的shared_ptr的源代码

template<class Y> void operator=( int i )
{
    reset(i);
}
template<class Y> void reset(int i)
{
    this_type(i).swap(*this);
}
template<class Y> void operator=( Y * p )
{
    reset(p);
}
shared_ptr(int i): px(0), pn()
{
}

The only thing is that if I do a = -1; it will compile and give me a null pointer, which shouldn't be a problem because normally you can't assign an integer value to a pointer.

唯一的事情是,如果我做 a = -1; 它会编译并给我一个空指针,这应该不是问题,因为通常你不能为指针分配一个整数值。

So my question is, is this a correct way to implement this or have I forgot cases that might crash the application? Because everywhere I looked, the only way I saw to get a nullpointer for a shared_ptr was to call the default constructor which isn't very elegant in code compared to: ptr = 0;.

所以我的问题是,这是实现这一点的正确方法还是我忘记了可能会使应用程序崩溃的情况?因为我所看到的任何地方,我看到的获得 shared_ptr 空指针的唯一方法是调用默认构造函数,与 ptr = 0; 相比,它在代码中不是很优雅。

回答by GManNickG

No. Do not change the source.It's like that for a reason and very smart people have decided that the way it's defined is better than whatever you're going to edit it to be.

不要更改源。就像那样是有原因的,非常聪明的人认为它的定义方式比你要编辑的方式更好。

What you have doesn't even make sense. You cannot assign an integer to a pointer, they are two different types, yet you've given it such semantics. You say: "...which shouldn't be a problem because normally you can't assign an integer value to a pointer", but you also said at the top of your question "I want to use shared_ptr just like I'd use an actual pointer". Well, which is it? Because assigning integers to pointers to set them to null is about as far from an actual pointer as you can get.

你所拥有的甚至没有意义。您不能将整数分配给指针,它们是两种不同的类型,但您已经给了它这样的语义。你说:“......这应该不是问题,因为通常你不能为指针分配一个整数值”,但你还在问题的顶部说“我想像我一样使用 shared_ptr使用实际的指针”。嗯,是哪个?因为将整数分配给指针以将它们设置为 null 与您所能获得的实际指针相差甚远。

You need to take a step back and realize what you want isn't always the best thing to do. You should revert those changes and use the class properly. I don't want to be mean but this is seriously not the route you want to go; it's dangerous, has nonsensical semantics, and is all around unmaintainable.

你需要退后一步,意识到你想要的并不总是最好的。您应该还原这些更改并正确使用该类。我不想刻薄,但这真的不是你想去的路线;它很危险,具有荒谬的语义,并且几乎无法维护。

回答by Ben Cottrell

shared_ptr implements a pointer-like interface so you can use the *and ->operator.

shared_ptr 实现了一个类似指针的接口,因此您可以使用*and->运算符。

A default-constructed (empty) shared_ptr will be equal to nullptrinternally, so you don't need to worry about assigning that explicitly. i.e.

默认构造的(空)shared_ptr 将在内部等于nullptr,因此您无需担心显式分配它。IE

std::shared_ptr<int> sh;
std::cout << ( sh.get() == nullptr ) << std::endl;

// Or alternatively:
std::cout << ( sh == nullptr ) << std::endl;


Also, (in my opinion) the most elegant way to use shared_ptr to create objects is the std::make_sharedfunction. This also has the added benefit of being slightly more efficient in some compilers (at least on MSVC++) due to some internal optimisation known as the "we know where you live idiom"

另外,(在我看来)使用 shared_ptr 创建对象的最优雅的方法是std::make_shared函数。由于一些称为“我们知道你住在哪里”的内部优化,这还具有在某些编译器(至少在 MSVC++ 上)稍微更有效的额外好处

#include <memory>
#include <string>

class foo
{
public:
    foo(std::string s, int n) {}
};

int main()
{
    auto p = std::make_shared<int>();
    auto q = std::make_shared<foo>("hello", 2);
}