我认为std::is_pointer在C++ 11中重载std::shared_ptr<T>也会产生正确,因为后者的表现非常像T*.
#include <type_traits>
namespace std {
template <typename T> struct is_pointer<shared_ptr<T>> : std::true_type {};
template <typename T> struct is_pointer<shared_ptr<T const>> : std::true_type {};
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么这个重载还没有包含在标准实现中.我忽略了一个陷阱吗?
作为替代方案,当然可以引入新的特征is_shared_ptr<T>.
实际上,我首先尝试了以下代码:
template <typename T>
struct is_pointer<shared_ptr<typename std::remove_cv<T>::type>>
: std::true_type
{};
Run Code Online (Sandbox Code Playgroud)
由于没有使用GCC 4.7编译
error: template parameters not used in partial specialization:
error: ‘T’
Run Code Online (Sandbox Code Playgroud) 关于boost::shared_ptrs的陷阱有几个有趣的问题.在其中一个中,有一个有用的提示,以避免指向boost::shared_ptr<Base>和boost::shared_ptr<Derived>相同的类型对象,Derived因为它们使用不同的引用计数,并可能过早地破坏对象.
我的问题:是否安全兼得boost::shared_ptr<T>并boost::shared_ptr<const T>点型的同一个对象T,还是将导致同样的问题?
由于boost::/std::shared_ptr具有类型擦除删除器的优点,你可以做很好的事情
#include <memory>
typedef std::shared_ptr<void> gc_ptr;
int main(){
gc_ptr p1 = new int(42);
gc_ptr p2 = new float(3.14159);
gc_ptr p3 = new char('o');
}
Run Code Online (Sandbox Code Playgroud)
由于保存了正确的删除器,这将正确删除所有指针.
如果您确保始终使用shared_ptr<Interface>(或make_shared<Interface>)创建接口的每个实现,您实际上是否需要virtual析构函数?virtual无论如何我会声明它,但我只是想知道,因为shared_ptr它将始终删除它初始化的类型(除非给出另一个自定义删除器).
我正在尝试使用libstdc ++(4.6.1)在clang ++(clang 3.1版(trunk 143100))中使用std :: shared_ptr.我有一个小的演示程序:
#include <memory>
int main()
{
std::shared_ptr<int> some(new int);
std::shared_ptr<int> other(some);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
可以使用以下方法构建:
clang++ -std=c++0x -o main main.cpp
Run Code Online (Sandbox Code Playgroud)
并给出以下错误输出:
main.cpp:6:23: error: call to deleted constructor of 'std::shared_ptr<int>'
std::shared_ptr<int> other(some);
^ ~~~~
/usr/include/c++/4.6/bits/shared_ptr.h:93:11: note: function has been explicitly marked
deleted here
class shared_ptr : public __shared_ptr<_Tp>
Run Code Online (Sandbox Code Playgroud)
由于某种原因,它需要删除构造函数,因为提供了移动构造函数(这是正确的行为).但为什么它可以编译(g ++(Ubuntu/Linaro 4.6.1-9ubuntu3)4.6.1.)?有人如何解决这个问题?
通过阅读c ++ 11 draft n3242,第20.7.2.5节,看起来我们在shared_ptr上有原子操作,这使我们能够在复杂的结构上进行无锁,而不必担心GC /内存泄漏.
但是,我无法在GCC-4.7.0中成功使用它.我只是测试了以下程序
#include <atomic>
#include <memory>
#include <string>
struct X {
int x;
double y;
std::string s;
};
int main() {
std::shared_ptr<X> x(new X);
auto p = std::atomic_load(&x);
}
Run Code Online (Sandbox Code Playgroud)
它有编译错误:
c.cpp:13:33: error: no matching function for call to ‘atomic_load(std::shared_ptr<X>*)’
Run Code Online (Sandbox Code Playgroud)
有谁知道我在这里错过了什么?或者只是gcc还没有实现呢?
在C++ 11上找不到多少,但仅限于提升.
考虑以下课程:
class State
{
std::shared_ptr<Graph> _graph;
public:
State( const State & state )
{
// This is assignment, and thus points to same object
this->_graph = std::make_shared<Graph>( state._graph );
// Deep copy state._graph to this->_graph ?
this->_graph = std::shared_ptr<Graph>( new Graph( *( state._graph.get() ) ) );
// Or use make_shared?
this->_graph = std::make_shared<Graph>( Graph( *( state._graph.get() ) ) );
}
};
Run Code Online (Sandbox Code Playgroud)
假设类Graph有一个复制构造函数:
Graph( const Graph & graph )
Run Code Online (Sandbox Code Playgroud)
我不想有这个 - > _ graph point/share同一个对象!相反,我希望这个 …
我正在考虑使用"自杀对象"来模拟游戏中的实体,即能够自行删除的对象.现在,一般的C++ 03的实现(普通旧delete this)不执行任何潜在指的自杀的对象,这就是为什么我使用的其他对象std::shared_ptr和std::weak_ptr.
现在进行代码转储:
#include <memory>
#include <iostream>
#include <cassert>
struct SuObj {
SuObj() { std::cout << __func__ << '\n'; }
~SuObj() { std::cout << __func__ << '\n'; }
void die() {
ptr.reset();
}
static std::weak_ptr<SuObj> create() {
std::shared_ptr<SuObj> obj = std::make_shared<SuObj>();
return (obj->ptr = std::move(obj));
}
private:
std::shared_ptr<SuObj> ptr;
};
int main() {
std::weak_ptr<SuObj> obj = SuObj::create();
assert(!obj.expired());
std::cout << "Still alive\n";
obj.lock()->die();
assert(obj.expired());
std::cout << "Deleted\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码似乎工作正常.但是,我想让别人去关注它.这段代码有意义吗?我是否盲目地驶入未定义的土地?我应该放弃键盘并立即开始艺术研究吗?
我希望这个问题能够充分缩小.看起来有点微小而且低级别的CR. …
最近我从C++ 11开始.我研究过weak_ptr.有两种获取原始指针的方法.
lock() 功能
shared_ptr<Foo> spFoo = wpPtr.lock();
if(spFoo) {
spFoo->DoSomething();
}
Run Code Online (Sandbox Code Playgroud)expired() 功能
if(!wpPtr.expired())
{
shared_ptr<Foo> spFoo = wpPtr.lock();
spFoo->DoSomething();
}
Run Code Online (Sandbox Code Playgroud)哪种方式更好?这两种方式有什么不同?
使用分离的分配创建shared_ptr时,必须在C++ 14 ctor和reset成员函数中提供显式删除函数.
using std::string;
using std::shared_ptr;
using std::default_delete;
int arr_size{};
...
auto string_arr_sptr_cpp14 =
shared_ptr<string[]>(new string[arr_size], default_delete<string[]>() );
string_arr_sptr_cpp14.reset(new string[arr_size], default_delete<string[]>() );
// define an explicit deleter,
// or otherwise, "delete ptr;" will internally be used incorrectly!
Run Code Online (Sandbox Code Playgroud)
通过在C++ 17中支持数组特性的shared_ptr,ctor和reset都不再需要那些?
auto string_arr_sptr_cpp17 = shared_ptr<string[]>(new string[arr_size]);
string_arr_sptr_cpp14.reset(new string[arr_size]);
// deduced delete function calls "delete[] ptr;" correctly now?
Run Code Online (Sandbox Code Playgroud) 当我们有一个希望拥有动态分配项的多个所有者的场景时,将使用shared_ptr.
问题是,我无法想象我们需要多个所有者的任何情况.我可以使用unique_ptr解决我可以成像的每个用例.
有人可以提供一个真实的用例示例,其中代码需要shared_ptr(并且根据需要,我的意思是作为智能指针的最佳选择)?而对于"现实生活",我指的是一些实用和务实的用例,而不是过于抽象和虚构的东西.