【问题标题】:shared_ptr null pointer and assignmentshared_ptr 空指针和赋值
【发布时间】:2012-04-22 08:07:07
【问题描述】:

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

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

但默认没有实现。

我通过添加更改了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()
{
}

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

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

【问题讨论】:

  • 文字0 是一个空指针常量,因此可以隐式转换为任何指针类型的空指针值
  • +1 "我修改了boost库的shared_ptr的源代码" ;)
  • 为什么不改用 C++11 nullptr

标签: c++ pointers null shared-ptr


【解决方案1】:

没有。 不要更改源代码。 这样做是有原因的,非常聪明的人认为定义它的方式比你要编辑的方式更好。

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

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

【讨论】:

  • 是的,你是对的。我想我只是懒惰,因为我不想更改所有内容,因为我之前有正常的指针并且正在更改为智能 ptr。我怀疑我做错了什么,这就是我问的原因:)
  • @MichaelFerris:没关系,但有时你只需要开始工作,尤其是在重构代码时。 :) 随着您的编码风格的改进,您会发现最好对事物进行明确的说明。虽然隐式功能对您来说意味着更少的工作,但通常对您来说意味着更少的清晰度和安全性。例如,仅查看return 0;,您会认为您返回的是 number 零,而不是空指针。但是当你说return boost::shared_ptr&lt;int&gt;(); 时没有混淆。事实上,新的 C++ 标准为 null 引入了一个新关键字:nullptr
  • 我什至不知道nullptr的存在。谢谢! :) 另外,我选择在标准库中使用 shared_ptr,这样我就不必携带像 boost 这样的大型库。还有很多东西要学;)
  • @MichaelFerris:如果你能用,一定要养成这个习惯。现在所有的主流编译器都支持它,而且非常有用。另外,欢迎使用 StackOverflow。
【解决方案2】:

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

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

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

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

另外,(在我看来)使用 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);
}

【讨论】:

    猜你喜欢
    • 2019-07-10
    • 2012-10-31
    • 2011-06-19
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 2010-10-11
    • 2023-04-02
    • 2013-05-16
    相关资源
    最近更新 更多