C++ 带有 boost::shared_ptr 的 NULL 指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/621220/
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 16:18:41  来源:igfitidea点击:

NULL pointer with boost::shared_ptr?

c++boostnullpointersshared-ptr

提问by

What's the equivalent to the following:

什么相当于以下内容:

std::vector<Foo*> vec;
vec.push_back(NULL);

when dealing with boost::shared_ptr? Is it the following code?

什么时候处理boost::shared_ptr?是下面的代码吗?

std::vector< boost::shared_ptr<Foo> > vec;
vec.push_back(boost::shared_ptr<Foo>());

Note: I may push back a lot of such objects. Should I declare a global static nullPtrobject somewhere? That way only one of them would have to be constructed:

注意:我可能会推回很多这样的对象。我应该在nullPtr某处声明一个全局静态对象吗?这样一来,只需要构建其中一个:

boost::shared_ptr<Foo> nullPtr;

回答by j_random_hacker

Your suggestion (calling the shared_ptr<T>constructor with no argument) is correct. (Calling the constructor with the value 0 is equivalent.) I don't think that this would be any slower than calling vec.push_back()with a pre-existing shared_ptr<T>, since construction is required in both cases (either direct construction or copy-construction).

您的建议(shared_ptr<T>不带参数调用构造函数)是正确的。(使用值 0 调用构造函数是等效的。)我认为这不会比vec.push_back()使用预先存在的调用慢shared_ptr<T>,因为在这两种情况下都需要构造(直接构造或复制构造)。

But if you want "nicer" syntax, you could try the following code:

但是如果你想要“更好”的语法,你可以尝试以下代码:

class {
public:
    template<typename T>
    operator shared_ptr<T>() { return shared_ptr<T>(); }
} nullPtr;

This declares a single global object nullPtr, which enables the following natural syntax:

这声明了一个全局对象nullPtr,它启用了以下自然语法:

shared_ptr<int> pi(new int(42));
shared_ptr<SomeArbitraryType> psat(new SomeArbitraryType("foonly"));

...

pi = nullPtr;
psat = nullPtr;

Note that if you use this in multiple translation units (source files), you'll need to give the class a name (e.g. _shared_null_ptr_type), move the definition of the nullPtrobject to a separate .cpp file, and add externdeclarations in the header file where the class is defined.

请注意,如果您在多个翻译单元(源文件)中使用它,则需要为类命名(例如_shared_null_ptr_type),将nullPtr对象的定义移动到单独的 .cpp 文件中,并extern在头文件中添加声明,其中类已定义。

回答by Larry Gritz

Well, this is legal:

嗯,这是合法的:

shared_ptr<Foo> foo;  /* don't assign */

And in this state, it doesn't point to anything. You can even test this property:

在这种状态下,它不指向任何东西。你甚至可以测试这个属性:

if (foo) {
    // it points to something
} else {
    // no it doesn't
}

So why not do this:

那么为什么不这样做:

std::vector < shared_ptr<Foo> > vec;
vec.push_back (shared_ptr<Foo>);   // push an unassigned one

回答by bdonlan

In C++0x, you can simply convert from nullptrto std::shared_ptr:

在 C++0x 中,您可以简单地将 from 转换nullptrstd::shared_ptr

std::vector< boost::shared_ptr<Foo> > vec;
vec.push_back(nullptr);

回答by m-sharp

You could declare a global nullPtrfor shared_ptr<Foo>. But if you pollute the global namespace, what would you call the global nullPtrfor shared_ptr<Bar>?

您可以nullPtrshared_ptr<Foo>. 但是,如果你污染全局命名空间,你会调用全局nullPtrshared_ptr<Bar>

Typically I declare the null ptr as a static in the class of the pointer.

通常我在指针的类中将空 ptr 声明为静态。

#include <boost\shared_ptr.hpp>

class Foo; // forward decl
typedef boost::shared_ptr<Foo> FooPtr;
class Foo
{
public:
    static FooPtr Null;
}
...
// define static in cpp file
FooPtr Foo::Null;
...
// use Foo Null
vec.push_back(Foo::Null);

That way each class has a static Null.

这样每个类都有一个静态空值。

回答by Robert S. Barnes

Here's something which I think is a bit simpler and works just fine

这是我认为有点简单并且工作正常的东西

( remember that typedefis your friend ):

(记住那typedef是你的朋友):

#include    <cstdlib>
#include    <vector>
#include    <iostream>
#include    <boost/shared_ptr.hpp>

typedef boost::shared_ptr< std::vector<char> > CharVecHandle;

inline CharVecHandle newCharVec(std::vector<char>::size_type size) {
    return CharVecHandle(new std::vector<char>(size));
}

inline CharVecHandle newCharVec(void) {
    return CharVecHandle();
}

int main ( void )
{
    CharVecHandle cvh = newCharVec();

    if (cvh == NULL) 
        std::cout << "It's NULL" << std::endl;
    else 
        std::cout << "It's not NULL" << std::endl;

    std::vector< CharVecHandle > cvh_vec;

    cvh_vec.push_back(newCharVec(64));
    cvh_vec.push_back(newCharVec());

    // or call the NULL constructor directly
    cvh_vec.push_back(CharVecHandle());

    return EXIT_SUCCESS;
}

回答by Christopher Dolan

Yes, declare a global static null pointer.

是的,声明一个全局静态空指针。