【发布时间】:2013-07-06 05:34:39
【问题描述】:
我喜欢 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.
因此,我想要的是“具有空初始化的原始指针”。比如:
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 )
{...}
...
更准确地说,我想要的是一种简单、廉价的类型,除了它的默认构造函数将其初始化为 nullptr 之外,它在各方面的行为都与原始指针完全相同。
我的问题:(1)标准库中是否已经存在这样的东西? (2) 如果不是,那么实现这种类型的最优雅/最小的方法是什么?
附:我对 Boost 或任何其他库不感兴趣,除非它可能是单个文件中的仅标头库。小巧和简单至关重要。
【问题讨论】:
-
你可以在类中初始化它:
lar *pr{};. -
这看起来像是一个你如何充分利用错误的工具?类型的问题。首先,您需要澄清为什么解决实际问题的方法是使用原始指针。除非这是合理的,否则考虑到不初始化它的脆弱性是没有问题的。
-
@DavidRodríguez-dribeas 来吧。原始指针仍然有一个有效的位置。我认为原始指针的使用不需要合理化。鉴于此,它们明显不同于需要显式初始化的“现代”指针。我认为仅凭这些事实就可以提出问题。
-
@OldPeculier:相反,原始指针应该是例外,并且作为例外应该仅在需要特别小心处理的少数组件中使用。如果您正在处理这种类型的特殊组件并且您确实付出了额外的注意,那么您可能不会忘记初始化。当您认为原始指针很常见并且习惯了它们时,问题就出现了,您变得更加粗心。在一个原始指针很少见的世界里,带有原始指针的代码已经很可疑,并且不太可能出现绕过审查的错误。
-
@jmucchiello 好伤心。像这样的问题真的是讨论软件设计哲学和 C++ 使用的正确场所吗?人们以各种方式使用 C++。生活,让生活!出于这个问题的目的,请假设某些 C++ 程序员有时有充分的理由使用原始指针并希望它们自动为空而不求助于类内或构造函数初始化。
标签: c++ pointers c++11 unique-ptr