使用从另一个具体 class 返回的 shared_ptr
Working with shared_ptr returned from another concrete class
我需要访问在不同具体 class 中实现的对象。所以我决定使用std::shared_ptr
。我想知道这里使用 std::shared_ptr
是否合适,如果不合适请建议我是否应该使用 std::weak_ptr
。到目前为止,我一直在使用原始指针,但现在我决定在我的项目中使用智能指针,但我无法决定我应该在这里使用哪一个。以下代码片段类似于我在我的项目中尝试做的事情。
#include <iostream>
#include <memory>
class data
{
public:
data()
{
std::cout<<"\n data constructor Called"<<std::endl;
}
~data()
{
std::cout<<"\n data destructor Called"<<std::endl;
}
int GetData()
{
return val;
}
void SetData(int & val)
{
this->val = val;
}
private:
int val;
};
class sample
{
public:
sample();
~sample();
void GetShared(std::shared_ptr<data> & arg);
std::shared_ptr<data> sPtr;
};
sample::sample()
{
sPtr = std::make_shared<data>();
}
sample::~sample()
{
}
void sample::GetShared(std::shared_ptr<data> & arg)
{
arg = sPtr;
}
int main()
{
int val = 40;
sample obj;
{
std::shared_ptr<data> temp1;
obj.GetShared(temp1);
temp1->SetData(val);
std::cout<<"\n Data : "<<temp1->GetData()<<std::endl;
} // Just to understand whether pointer gets deleted if temp1 goes out of scope.
{
std::shared_ptr<data> temp2;
obj.GetShared(temp2);
val = 20;
temp2->SetData(val);
std::cout<<"\n Data : "<<temp2->GetData()<<std::endl;
}
return 0;
}
shared_ptr 和 weak_ptr 的区别在于 weak_ptr 不会增加对象的引用计数并防止对象被删除。
这有利有弊,如果你在获取指针后进行异步操作,不确定提供数据的对象是否已经销毁,那么你可以使用weak_ptr检查你是否还有访问对象。
如果不是,则保持简单并使用 shared_ptr。
当您没有明确的资源所有者时,您可以使用 shared_pointer
来共享某些资源的所有权。
如果您不知道 obj
在 temp1
和 temp2
完成 data
之前是否超出范围,这将很有用。然而,在这个例子中,很明显 obj
和它持有的 data
对象 将 比用户长寿。在那种情况下,您也可以 return 普通指针,或者对数据的引用。
使用 shared_pointer
(或 weak_pointer
)不会给您带来任何好处,只会增加复杂性。
在你的代码中
sample obj;
{
std::shared_ptr<data> temp1;
obj.GetShared(temp1);
temp1->SetData(val);
std::cout<<"\n Data : "<<temp1->GetData()<<std::endl;
} // Just to understand whether pointer gets deleted if temp1 goes out of scope.
数据不会被删除,因为它指向 obj
持有的东西,它仍然存在。
我认为答案应该取决于 data
对象在其对应的 sample
对象死亡后是否可以存活:
- 如果是,那么它应该return一个
std::shared_ptr
。
- 如果没有,那么它应该return一个
std::weak_ptr
。
您有两个问题需要问自己。
1) 从 sample
获取指针的 调用对象 会比 sample
对象长寿吗?
如果不是那么sample
应该使用std::unique_ptr
和return一个原始指针或 reference.
2) 如果 调用对象 确实比 sample
对象长寿,是否介意 data
对象先于它被销毁?
If not then return a std::weak_ptr
可用于在使用前测试 data
对象是否仍然存在。
否则 return std::shared_ptr
保证 data
对象与 调用对象.
总结:
如果调用对象不会超过sample
对象:
class sample
{
std::unique_ptr<data> ptr; // UNIQUE (not shared)
public:
data* GetData() { return ptr.get(); }
};
如果 调用对象 可能比 sample
对象长寿,但不关心 data
对象是否长寿:
class sample
{
std::shared_ptr<data> ptr;
public:
std::weak_ptr<data> GetData() { return ptr; }
};
如果 调用对象 可能比 sample
对象活得更久,并且需要 data
对象来维持生命:
class sample
{
std::shared_ptr<data> ptr;
public:
std::shared_ptr<data> GetData() { return ptr; }
};
我需要访问在不同具体 class 中实现的对象。所以我决定使用std::shared_ptr
。我想知道这里使用 std::shared_ptr
是否合适,如果不合适请建议我是否应该使用 std::weak_ptr
。到目前为止,我一直在使用原始指针,但现在我决定在我的项目中使用智能指针,但我无法决定我应该在这里使用哪一个。以下代码片段类似于我在我的项目中尝试做的事情。
#include <iostream>
#include <memory>
class data
{
public:
data()
{
std::cout<<"\n data constructor Called"<<std::endl;
}
~data()
{
std::cout<<"\n data destructor Called"<<std::endl;
}
int GetData()
{
return val;
}
void SetData(int & val)
{
this->val = val;
}
private:
int val;
};
class sample
{
public:
sample();
~sample();
void GetShared(std::shared_ptr<data> & arg);
std::shared_ptr<data> sPtr;
};
sample::sample()
{
sPtr = std::make_shared<data>();
}
sample::~sample()
{
}
void sample::GetShared(std::shared_ptr<data> & arg)
{
arg = sPtr;
}
int main()
{
int val = 40;
sample obj;
{
std::shared_ptr<data> temp1;
obj.GetShared(temp1);
temp1->SetData(val);
std::cout<<"\n Data : "<<temp1->GetData()<<std::endl;
} // Just to understand whether pointer gets deleted if temp1 goes out of scope.
{
std::shared_ptr<data> temp2;
obj.GetShared(temp2);
val = 20;
temp2->SetData(val);
std::cout<<"\n Data : "<<temp2->GetData()<<std::endl;
}
return 0;
}
shared_ptr 和 weak_ptr 的区别在于 weak_ptr 不会增加对象的引用计数并防止对象被删除。
这有利有弊,如果你在获取指针后进行异步操作,不确定提供数据的对象是否已经销毁,那么你可以使用weak_ptr检查你是否还有访问对象。
如果不是,则保持简单并使用 shared_ptr。
当您没有明确的资源所有者时,您可以使用 shared_pointer
来共享某些资源的所有权。
如果您不知道 obj
在 temp1
和 temp2
完成 data
之前是否超出范围,这将很有用。然而,在这个例子中,很明显 obj
和它持有的 data
对象 将 比用户长寿。在那种情况下,您也可以 return 普通指针,或者对数据的引用。
使用 shared_pointer
(或 weak_pointer
)不会给您带来任何好处,只会增加复杂性。
在你的代码中
sample obj;
{
std::shared_ptr<data> temp1;
obj.GetShared(temp1);
temp1->SetData(val);
std::cout<<"\n Data : "<<temp1->GetData()<<std::endl;
} // Just to understand whether pointer gets deleted if temp1 goes out of scope.
数据不会被删除,因为它指向 obj
持有的东西,它仍然存在。
我认为答案应该取决于 data
对象在其对应的 sample
对象死亡后是否可以存活:
- 如果是,那么它应该return一个
std::shared_ptr
。 - 如果没有,那么它应该return一个
std::weak_ptr
。
您有两个问题需要问自己。
1) 从 sample
获取指针的 调用对象 会比 sample
对象长寿吗?
如果不是那么sample
应该使用std::unique_ptr
和return一个原始指针或 reference.
2) 如果 调用对象 确实比 sample
对象长寿,是否介意 data
对象先于它被销毁?
If not then return a std::weak_ptr
可用于在使用前测试 data
对象是否仍然存在。
否则 return std::shared_ptr
保证 data
对象与 调用对象.
总结:
如果调用对象不会超过sample
对象:
class sample
{
std::unique_ptr<data> ptr; // UNIQUE (not shared)
public:
data* GetData() { return ptr.get(); }
};
如果 调用对象 可能比 sample
对象长寿,但不关心 data
对象是否长寿:
class sample
{
std::shared_ptr<data> ptr;
public:
std::weak_ptr<data> GetData() { return ptr; }
};
如果 调用对象 可能比 sample
对象活得更久,并且需要 data
对象来维持生命:
class sample
{
std::shared_ptr<data> ptr;
public:
std::shared_ptr<data> GetData() { return ptr; }
};