2012-04-22 232 views
4

我想使用shared_ptr就像我会使用一个实际的指针。我希望能够做到像shared_ptr空指针和分配

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

但它没有默认实现。

我通过添加

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() 
{ 
} 

改变升压库的shared_ptr的源代码的唯一事情是,如果我做= -1;它会编译并给我一个空指针,这应该不成问题,因为通常你不能给一个指针赋一个整数值。

所以我的问题是,这是为了实现这个还是有我忘了,可能会导致应用程序崩溃的情况下正确的方法是什么?因为在我看来,我看到为shared_ptr获取空指针的唯一方式是调用默认的构造函数,这在代码中不是很优雅,与之相比:ptr = 0 ;.

+0

文字上的'0'是一个_null指针常量_已经可以隐式转换为任何指针类型的_null指针值_。 – 2012-04-22 08:27:24

+1

+1“我更改了boost库的shared_ptr的源代码”;) – Offirmo 2013-02-06 11:58:35

+0

为什么不使用C++ 11'nullptr'代替? – Venemo 2014-03-09 13:15:16

回答

24

不要更改源。这就像是出于某种原因,非常聪明的人已经决定,它的定义方式比任何你想要编辑的方式都要好。

你有什么,甚至没有任何意义。你不能给一个指针赋一个整数,它们是两种不同的类型,但你已经给了它这样的语义。你说:“......这不应该是一个问题,因为通常你不能指定一个整数值给一个指针”,但你也在问题的顶部说道:“我想用shared_ptr就像我一样使用实际指针“。那么,这是什么?由于将指向整数的指针设置为null,因此您可以获得与实际指针差不多的距离。

你需要退后一步,实现你想要的东西并不总是最好的事情。您应该恢复这些更改并正确使用该类。我不想说卑鄙,但这不是你想要走的路线;它很危险,具有无意义的语义,并且全都无法维护。

+0

是的,你说得对。我想我只是懒惰,因为我不想改变一切,因为我有正常的指针之前,并正在改变为智能ptr。 我怀疑我在做什么是错误的,这就是为什么我问:) – 2012-04-22 08:33:22

+0

@MichaelFerris:这没关系,但有时你只需要开始工作,尤其是在重构代码时。 :)随着你的编码风格的提高,你会发现最好清楚一些事情。虽然隐含的功能对您而言意味着更少的工作,但通常意味着您的清晰度和安全性会降低。例如,只要看一下'return 0;',你会认为你返回的是* number *零,而不是一个空指针。但是当你说'return boost :: shared_ptr ();'时没有混淆。事实上,这很大程度上是为了让新的C++标准为null引入一个新的关键字:'nullptr'。 – GManNickG 2012-04-22 08:39:46

+0

我甚至不知道nullptr的存在。谢谢! :) 另外,我选择使用标准库中的shared_ptr,所以我不必携带像boost这样的巨大库。还有很多东西要学习;) – 2012-04-22 08:47:05

8

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

内部默认构建的(空的)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); 
}