在C++中自我初始化为nullptr的简单原始指针

Old*_*ier 3 c++ pointers unique-ptr c++11

我喜欢C++ 11中的新指针类型,但有时我还需要一个原始指针.然而,让我对C++中的"原​​始"类型越来越感到悲伤的是,当没有给出明确的值时,他们习惯于初始化为未定义.因为我经常使用std :: shared_ptr <>之类的东西,所以需要将原始指针初始化为null感觉越来越脆弱和不必要.我在说:

class foo
{
    ...
    std::shared_ptr< bar > pb;   // Initially null in whatever constructor.
    std::unique_ptr< dar > pd;   // Likewise.
    std::weak_ptr< gar > pg;     // And again.
    lar* pr;                     // Uh-oh! Who knows what this is? Better remember to initialize...
};

foo::foo( int j )
: pr( nullptr )
{...}

foo::foo( const string& s )
: pr( nullptr )
{...}

... etc.: many tedious and error-prone constructor definitions follow.
Run Code Online (Sandbox Code Playgroud)

因此,我想要的是"具有空初始化的原始指针".就像是:

class foo
{
    ...
    std::shared_ptr< bar > pb;   // Initially null in whatever constructor.
    std::unique_ptr< dar > pd;   // Likewise.
    std::weak_ptr< gar > pg;     // And again.
    raw_ptr< lar > pr;           // Once more with feeling.
};

foo::foo( int j )
{...}                            // No explicit pointer initialization necessary.

foo::foo( const string& s )
{...}

...
Run Code Online (Sandbox Code Playgroud)

更准确地说,我想要的是一个简单,廉价的类型,除了它的默认构造函数将其初始化为nullptr之外,其作用与各种方式的原始指针完全相同.

我的问题:(1)标准库中是否已存在这样的事情?(2)如果没有,那么完成这种类型实现的最优雅/最小的方法是什么?

PS我对Boost或任何其他库不感兴趣,除非它可能是单个文件中的头文件库.小巧和简约是至关重要的.

Pra*_*ian 13

C++ 11允许在类中初始化数据成员.

class foo
{
  // ...
  lar *pr = nullptr;
};
Run Code Online (Sandbox Code Playgroud)

除非你在构造函数中指定另一个值,否则它将始终初始化prnullptr.

  • @OldPeculier,从问题中删除C++ 11标签,我将100%同意你的意见.所有兼容的C++ 11工具链都适用于这个答案. (5认同)
  • @OldPeculier我将不得不接受你的意见.无论这些原始指针被用于什么,如果它们真的被声明为指针类型的数据成员,我不明白为什么很难将它们初始化为某个值. (2认同)

Che*_*etS 8

看起来您需要"世界上最愚蠢的智能指针",它已被提议作为未来C++标准模板库的补充.你可以在这里看到这个建议:"关于世界上最愚蠢的智能指针的提案",在这里: "关于世界上最愚蠢的智能指针的提案,v2",在这里:"关于世界上最愚蠢的智能指针的提案,v3"

该提案包含一个潜在的部分实现,您可以调整它以适用于您当前使用的编译器.该实现类似于Mark Ransom提供的almost_raw_ptr解决方案.对exempt_ptr的网络搜索将提供更多详细信息.

世界上最愚蠢的智能指针的提议,v3已经"将exempt_ptr重命名为observer_ptr",请参阅链接的其他更改.


Mar*_*som 5

template<typename T>
class almost_raw_ptr
{
public:
    almost_raw_ptr(T* p = nullptr) : m_p(p) {}
    T* operator=(T* p) { m_p = p; return p; }
    operator T*() const { return m_p; }
    T* operator->() const { return m_p; }
    T& operator*() const { return *m_p; }
    T& operator[](int i) const { return m_p[i]; }

private:
    T* m_p;
};
Run Code Online (Sandbox Code Playgroud)

如果您需要指针或对实际原始指针的引用,这将不起作用,但它应该适用于其他所有内容.

  • @OldPeculier,与原始指针的自动转换将满足大多数比较和副本的需求. (3认同)
  • @jmucchiello,开销不会比任何其他智能指针类型差.内联扩展无法保证,但标准库模板依赖于它以获得可接受的性能,此模板也不例外.查看`std :: vector`的定义并告诉我你为`operator []`找到了什么. (3认同)