该cplusplus.com shared_ptr页面召唤出一个区分空 std::shared_ptr和空 shared_ptr.该cppreference.com页面没有明确叫出区别,但同时使用"空",并比较nullptr其描述std::shared_ptr行为.
空和空之间有区别shared_ptr吗?这种混合行为指针有用例吗?非空null是否shared_ptr有意义?是否会出现正常使用情况(即如果你没有明确构造一个),你最终会得到一个空但非空的shared_ptr?
如果您使用的是Boost版本而不是C++ 11版本,那么这些答案中的任何一个都会改变吗?
将shared_ptr派生类型传递给采用shared_ptr基类型的函数的最佳方法是什么?
我通常通过shared_ptr引用传递s以避免不必要的副本:
int foo(const shared_ptr<bar>& ptr);
Run Code Online (Sandbox Code Playgroud)
但如果我尝试做类似的事情,这不起作用
int foo(const shared_ptr<Base>& ptr);
...
shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
Run Code Online (Sandbox Code Playgroud)
我可以用
foo(dynamic_pointer_cast<Base, Derived>(bar));
Run Code Online (Sandbox Code Playgroud)
但这似乎是次优的,原因有两个:
dynamic_cast对于简单的派生到基础演员来说,A 似乎有点过分.dynamic_pointer_cast创建一个指向传递给函数的副本(虽然是临时的).有更好的解决方案吗?
原来这是一个缺少头文件的问题.此外,我在这里尝试做的是一个反模式.通常,
不影响对象生命周期的函数(即对象在函数持续时间内保持有效)应采用普通引用或指针,例如int foo(bar& b).
使用对象的函数(即,是给定对象的最终用户)应该采用unique_ptrby值,例如int foo(unique_ptr<bar> b).std::move调用者应该将值放入函数中.
延长对象生命周期的函数应采用shared_ptrby值,例如int foo(shared_ptr<bar> b).避免循环引用的通常建议适用.
有关详细信息,请参阅Herb Sutter的回归基础讲座.
什么是一个相当于static_cast用boost::shared_ptr?
换句话说,我该如何重写以下内容
Base* b = new Derived();
Derived* d = static_cast<Derived*>(b);
Run Code Online (Sandbox Code Playgroud)
什么时候用shared_ptr?
boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = ???
Run Code Online (Sandbox Code Playgroud) 我正在阅读Scott Meyers的"Effective C++"一书.有人提到有内置指针tr1::shared_ptr和tr1::weak_ptr行为,但它们跟踪tr1::shared_ptrs指向对象的数量.
这称为引用计数.这在防止非循环数据结构中的资源泄漏方面效果很好,但是如果两个或多个对象包含tr1::shared_ptrs形成循环,则循环可以使彼此的引用计数保持在零以上,即使所有指向循环的外部指针都已被破坏.
那是tr1::weak_ptrs进来的地方.
我的问题是循环数据结构如何使引用计数高于零.我恳请一个示例C++程序.问题是如何解决的weak_ptrs?(再次,请举例).
我想在GCC中启用对C++ 0x的支持-std=c++0x.我并不一定需要GCC 4.5中的任何当前支持的C++ 11功能(很快就会有4.6),但我想开始习惯它们.例如,在我使用迭代器的一些地方,auto类型会很有用.
但同样,我不需要任何当前支持的功能.这里的目标是鼓励我将新标准的特征融入我的编程"词汇"中.
根据您对C++ 11支持的了解,在GCC中启用它是一个好主意,然后通过例如从使用切换boost::shared_ptr到std::shared_ptr专用来实现它,因为两者不混合?
PS:我知道这个比较不同口味的好问题,shared_ptr但是我要求在标准最终确定之前提出更高级别的建议.另一种说法是,当像GCC这样的编译器说它支持"实验性功能"时,这是否意味着我可能会在编译过程中遇到奇怪的错误,这些错误将成为主要的时间汇,并且是StackOverflow上一个神秘问题的来源?
编辑:我决定退回,std::shared_ptr因为我只是不相信它在GCC 4.5中的支持,如本问题中的示例所示.
该标准提供了一个模板特化std::unique_ptr,正确调用delete[]其析构函数:
void func()
{
std::unique_ptr< int[] > arr(new int[10]);
.......
}
Run Code Online (Sandbox Code Playgroud)
由于std::shared_ptr这种专业化不可用,因此有必要提供一个正确调用的删除器delete[]:
void func()
{
// Usage
shared_ptr array (new double [256], [](double* arr) { delete [] arr; } );
..............
}
Run Code Online (Sandbox Code Playgroud)
这只是一个疏忽吗?(以同样的方式存在std::copy_if)或是否有原因?
双方unique_ptr并shared_ptr接受定制的析构函数他们所拥有的对象上调用.但在的情况下unique_ptr,析构函数作为一个模板参数传递类,而类型shared_ptr的自定义析构函数将被指定为一个模板参数的构造函数.
template <class T, class D = default_delete<T>>
class unique_ptr
{
unique_ptr(T*, D&); //simplified
...
};
Run Code Online (Sandbox Code Playgroud)
和
template<class T>
class shared_ptr
{
template<typename D>
shared_ptr(T*, D); //simplified
...
};
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会有这样的差异.需要什么?
考虑:
struct SomethingThatsABase
{
virtual bool IsChildOne() const { return false; }
virtual bool IsChildTwo() const { return false; }
};
struct ChildOne : public SomethingThatsABase
{
virtual bool IsChildOne() const { return true; }
};
struct ChildTwo : public SomethingThatsABase
{
virtual bool IsChildTwo() const { return true; }
};
void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne)
{
//Does stuff
}
void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr)
{
if (ptr->IsChildOne())
{
SomeClientExpectingAChildOne(ptr); //Oops.
//Hmm.. can't static_cast here, because we need a `shared_ptr` out of …Run Code Online (Sandbox Code Playgroud) 我有一个关于C++ 11最佳实践的问题.清除shared_ptr时,我应该使用reset()没有参数的函数,还是应该设置shared_ptr为nullptr?例如:
std::shared_ptr<std::string> foo(new std::string("foo"));
foo.reset();
foo = nullptr;
Run Code Online (Sandbox Code Playgroud)
是否存在任何真正的差异,或者两种方法都存在优势/劣势?
我在整个应用程序中广泛使用std :: tr1 :: shared_ptr.这包括在函数参数中传递对象.考虑以下:
class Dataset {...}
void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...
Run Code Online (Sandbox Code Playgroud)
虽然通过shared_ptr传递数据集对象可以保证它在f和g中的存在,但是这些函数可能会被调用数百万次,这会导致很多shared_ptr对象被创建和销毁.这是最近一次运行的平坦gprof配置文件的片段:
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 9.74 295.39 35.12 2451177304 0.00 0.00 std::tr1::__shared_count::__shared_count(std::tr1::__shared_count const&) 8.03 324.34 28.95 2451252116 0.00 0.00 std::tr1::__shared_count::~__shared_count()
因此,大约17%的运行时用于使用shared_ptr对象进行引用计数.这是正常的吗?
我的应用程序的很大一部分是单线程的,我正在考虑重写一些函数
void f( const Dataset& ds ) {...}
Run Code Online (Sandbox Code Playgroud)
并替换电话
shared_ptr< Dataset > pds( new Dataset(...) );
f( pds …Run Code Online (Sandbox Code Playgroud) c++ ×10
shared-ptr ×10
c++11 ×8
boost ×2
casting ×1
downcast ×1
nullptr ×1
performance ×1
reset ×1
static-cast ×1
std ×1
stl ×1
unique-ptr ×1
weak-ptr ×1