我无法理解std::enable_shared_from_this::shared_from_this
如何返回与现有指针共享所有权的共享pinter。换句话说,你做this:
std::shared_ptr<Foo> getFoo() { return shared_from_this(); }
因此,当您致电getFoo
时,与其他shared_ptr
分享所有权的原因是什么,而不是创建拥有相同shared_ptr
的单独this
shared_ptr
}。
我需要理解这一点,以便能够理解如何从某个对象创建shared_ptr,这些对象都会增加相同的引用计数而不会初始化单独的onCreate
。
答案 0 :(得分:23)
enable_shared_from_this<T>
有weak_ptr<T>
个数据成员。 shared_ptr<T>
构造函数可以检测T
是否派生自enable_shared_from_this<T>
。如果是,shared_ptr<T>
构造函数会将*this
(shared_ptr<T>
)分配给weak_ptr
中的enable_shared_from_this<T>
数据成员。然后,shared_from_this()
可以从shared_ptr<T>
创建weak_ptr<T>
。
可能的实施示例:
template<class D>
class enable_shared_from_this {
protected:
constexpr enable_shared_from_this() { }
enable_shared_from_this(enable_shared_from_this const&) { }
enable_shared_from_this& operator=(enable_shared_from_this const&) {
return *this;
}
public:
shared_ptr<T> shared_from_this() { return self_.lock(); }
shared_ptr<T const> shared_from_this() const { return self_.lock(); }
private:
weak_ptr<D> self_;
friend shared_ptr<D>;
};
template<typename T>
shared_ptr<T>::shared_ptr(T* ptr) {
// ...
// Code that creates control block goes here.
// ...
// NOTE: This if check is pseudo-code. Won't compile. There's a few
// issues not being taken in to account that would make this example
// rather noisy.
if (is_base_of<enable_shared_from_this<T>, T>::value) {
enable_shared_from_this<T>& base = *ptr;
base.self_ = *this;
}
}
答案 1 :(得分:0)
我正在提交一种替代方法,其中EnabledSharedFromThis实现不会增加从其继承类的额外指针的开销。 这是一个非常粗糙的解决方案,我有兴趣了解一种更有效的实现EnabledSharedFromThis的解决方案。
#include <iostream>
#include <type_traits>
#include <map>
#include <memory>
using namespace std;
template<typename T>
struct EnableShareFromThis;
template<typename T>
struct Shr_ptr;
//SHARED POINTER implementation with lot of flaws :)
template<typename T>
struct Shr_ptr{
//very brute approach to solving this problem.
static map<T*, Shr_ptr<T>*> ENABLE_SHARE_STORE;
protected:
T* raw;
int* ref;
public:
Shr_ptr():raw(nullptr), ref(nullptr){
cout << "Shr_ptr...." << endl;
}
Shr_ptr(T* p, int* c):raw(p), ref(c){
++(*ref);
cout << "Shr_ptr ctr with raw & ref..." << *c << endl;
}
Shr_ptr(T* p):raw(p), ref(new int(1)){
if(std::is_base_of<EnableShareFromThis<T>, T>::value)
{
cout << " is_base_of<EnableShareFromThis" << endl;
ENABLE_SHARE_STORE.insert(make_pair(static_cast<T*>(raw), this));
}
cout << "Shr_ptr...param...ctr..ref=" << *ref << endl;
}
bool operator==(const Shr_ptr& rhs){
return (raw == rhs.raw) && (*ref == *rhs.ref);
}
bool operator<(const Shr_ptr& rhs){
return raw < rhs.raw && *ref < *rhs.ref;
}
Shr_ptr& operator=(const Shr_ptr& rhs){
if(this == &rhs)
return *this;
raw = rhs.raw;
++(*rhs.ref);
ref = rhs.ref;
cout << "Shr_ptr...operator=....ref=" << *ref << endl;
return *this;
}
Shr_ptr(const Shr_ptr& rhs){
if(rhs.raw)
raw = rhs.raw;
if(rhs.ref)
{
++(*rhs.ref);
ref = rhs.ref;
cout << "Shr_ptr...cpy ctr...ref=" << *ref << endl;
}
}
Shr_ptr(Shr_ptr&& rhs){
cout << "Shr_ptr...mv ctr...." << endl;
if(rhs.raw)
{
raw = rhs.raw;
rhs.raw = nullptr;
}
if(rhs.ref)
{
++(*rhs.ref);
ref = rhs.ref;
cout << "Shr_ptr...mv ctr...ref=" << *ref << endl;
rhs.ref = nullptr;
}
}
T* operator->(){
return raw;
}
T* get() const{return raw;}
T* get() {return raw;}
int use_count()
{
return *ref;
}
~Shr_ptr()
{
cout << "~Shr_ptr ref=" << *ref << endl;
--*ref;
if(*ref==0)
{
Shr_ptr<T>::ENABLE_SHARE_STORE.erase(raw);
delete raw;
raw = nullptr;
}
}
};
template<typename T>
map<T*, Shr_ptr<T>*> Shr_ptr<T>::ENABLE_SHARE_STORE;
template<typename T>
struct EnableShareFromThis{
EnableShareFromThis()
{
cout << "EnableShareFromThis ctr..." << endl;
}
Shr_ptr<T> SharedFromThis()
{
auto itr = Shr_ptr<T>::ENABLE_SHARE_STORE.find(static_cast< T*>(this));
if (itr != Shr_ptr<T>::ENABLE_SHARE_STORE.end())
{
cout << " SharedFromThis called....." << endl;
return *itr->second;
}
return Shr_ptr<T>(static_cast< T*>(this));
}
};
使用EnableShareFromThis的类
struct A: EnableShareFromThis<A>{
A(){cout << "A ctr....m" << endl;}
~A(){cout << "A dtr....m" << endl;}
Shr_ptr<A> f()
{
return SharedFromThis();
}
};
没有EnableShareFromThis的类
struct B{
B(){cout << "B ctr...." << endl;}
~B(){cout << "B dtr...." << endl;}
};
测试用例
void test()
{
//Check size of different objects, std enabled_from_this does not add extra size to A
cout << "Size of A=" << sizeof(A) << " size of Shr_ptr=" << sizeof(Shr_ptr<A>) << " std::shr_ptr size=" << sizeof(shared_ptr<A>) << endl;
Shr_ptr<A> p1(new A());
cout << endl;
cout << "{" << endl;
{
//Get SharedFromThis
Shr_ptr<A> p5 = p1->f();
Shr_ptr<A> p6 = p5->f();
cout << "p5 use_count=" << p5.use_count() << ", p1 use_count=" << p1.use_count() << endl;
}
cout << "}" << endl;
cout << endl;
cout << "{" << endl;
{
//Without SharedFromThis
Shr_ptr<B> p7(new B());
cout << "p7 use_count=" << p7.use_count() << endl;
}
cout << "}" << endl;
cout << endl;
}
int main()
{
test();
return 0;
}