(原创)智能指针拾遗 - qicosmos(江南) - 博客园
shared_ptr的 reset用法 - tycoon3 - 博客园 (cnblogs.com)
手写智能指针(类)_L_smartworld的博客-CSDN博客_手写智能指针
c++智能指针出现后是不是就可以不用new和delete了?
c++智能指针出现后是不是就可以不用new和delete了? - 知乎
c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
c++11 智能指针 unique_ptr、shared_ptr与weak_ptr - lsgxeva - 博客园
(717条消息) c++11特性(六)智能指针_智能指针赋值_钢钢钢很不爽的博客-CSDN博客
(680条消息) 避免使用c/c++指针引发的问题_c++如何防止函数结束释放_饮风而醉的博客-CSDN博客
(699条消息) 从源码理解智能指针(二)—— shared_ptr、weak_ptr_HerofH_的博客-CSDN博客
为什么多线程读写 shared_ptr 要加锁?_xuhao_xuhao的专栏-程序员ITS304 - 程序员ITS304
C++11中智能指针的原理、使用、实现 - wxquare - 博客园
c++智能指针——原理与实现
c++智能指针——原理与实现_runner668的博客-CSDN博客_c++智能指针
因为智能指针用到计数器,为了提升性能(实际影响微不足道)要尽量减少临时智能指针变量的产生,尽量用引用或左值引用,用std::move捕捉右值。
shared_ptr的线程安全性_DXT的博客-CSDN博客_shared_ptr线程安全
shared_ptr的reference count是线程安全的,但是指向的对象不是线程安全的!
(689条消息) [c++] 智能指针shared_ptr_shared_ptr获取值_wabil的博客-CSDN博客
//Demo1.cc
#include <iostream>
#include<memory>
using namespace std;
int main()
{
int a = 120;
shared_ptr<int> pt = make_shared<int>(a);
//连续make_shared会把上一次的自动析构掉,释放掉
pt = make_shared<int>(50);
int *pRaw = pt.get();
cout<< "rawValue="<<*pRaw<<endl; //you will see =120
return 0;
}
//MakeFile: g++ Demo1.cc ;./a.out
//连续make_shared 一个指针 会把上一次的自动析构掉,释放掉
关于c ++:std :: shared_ptr-将共享指针作为参数传递的最佳实践 | 码农家园 (codenong.com)
class ServiceB {
public:
ServiceB() {}
};
class ServiceA {
public:
ServiceA(std::shared_ptr<ServiceB>& serviceB)
: _serviceB(serviceB) {
}
private:
std::shared_ptr<ServiceB> _serviceB;
};
class Root {
public:
Root()
: _serviceB(std::shared_ptr<ServiceB>(new ServiceB())),
_serviceA(std::unique_ptr<ServiceA>(new ServiceA(_serviceB))) {
}
private:
std::shared_ptr<ServiceB> _serviceB;
std::unique_ptr<ServiceA> _serviceA;
};
shared_ptr使用场景、陷阱、性能分析,使用建议
shared_ptr使用场景、陷阱、性能分析,使用建议_INGNIGHT的专栏-CSDN博客_shared_ptr使用场景
C++11使用make_shared的优势和劣势 - 南哥的天下 - 博客园
C++ 原始指针、shared_ptr、unique_ptr分别在什么场景下使用
C++ 原始指针、shared_ptr、unique_ptr分别在什么场景下使用_知乎:C加加辅导袁老师的博客-CSDN博客
-22 增加了unique_ptr指针的使用
1 智能指针天生负责对象生命期管理;所以生命期对象全都由unique_ptr和shared_ptr来管理。
2 原始指针天生不负责对象生命周期管理,这时候使用shared_ptr来传递动态对象和使用原始指针来传递动态对象本质上没有区别,为了简单还是传递原始指针更好一些。
下面是示例代码:
class T3;
class T2;
class T1;
class A
{
T3* m_t2;//创建和释放都由A之外的代码管理,A只负责(借用)使用;业务逻辑上保证A在使用m_t2指向的对象的时候,对象始终是存在的
shared_ptr<T2> m_t2;//由加载程序创建m_t2指向的对象,执行时,交给A来管理,涉及动态对象的管理权的交接
unique_ptr<T1> m_t1;//A管理该对象的生命周期,A的构造函数构造m_t1, A的析构函数释放m_t1;
};
很多人怕写C/C++ 程序就是因为指针,因为指针给了程序员高度的自由,同样也赋予了高度的责任,稍有不慎就导致内存泄漏。其实写C++ 可以完全不用指针,尤其C++ 11对智能指针作了进一步的升级,在不需要使用任何裸指针的前提下也可以写出高效的C++ 程序。C++ 11中定义了unique_ptr
、shared_ptr
与weak_ptr
三种智能指针(smart pointer),都包含在<memory>
头文件中。智能指针可以对动态分配的资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。
shared_ptr
shared_ptr
允许多个该智能指针共享“拥有”同一堆分配对象的内存,这通过引用计数(reference counting)实现,会记录有多少个shared_ptr共同指向一个对象,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。支持复制和赋值操作。
weak_ptr
weak_ptr
是为配合shared_ptr
而引入的一种智能指针来协助shared_ptr
工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用计数的增加或减少。没有重载 *
和 ->
但可以使用lock获得一个可用的shared_ptr
对象
weak_ptr
的使用更为复杂一点,它可以指向shared_ptr
指针指向的对象内存,却并不拥有该内存,而使用weak_ptr
成员lock
,则可返回其指向内存的一个share_ptr
对象,且在所指对象内存已经无效时,返回指针空值nullptr。
注意:weak_ptr并不拥有资源的所有权,所以不能直接使用资源。 可以从一个weak_ptr
构造一个shared_ptr
以取得共享资源的所有权。
asyncTask([media_stream] (std::shared_ptr<WebRtcConnection> connection) {
boost::mutex::scoped_lock lock(connection->update_state_mutex_);
ELOG_DEBUG("%s message: Adding mediaStream, id: %s", connection->toLog(), media_stream->getId().c_str());
connection->media_streams_.push_back(media_stream);
});
void WebRtcConnection::asyncTask(std::function<void(std::shared_ptr<WebRtcConnection>)> f) {
std::weak_ptr<WebRtcConnection> weak_this = shared_from_this();
worker_->task([weak_this, f] {
if (auto this_ptr = weak_this.lock()) {
f(this_ptr); //this_ptr = std::shared_ptr<erizo::WebRtcConnection>
}
});
}
weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象, 从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr
(699条消息) C++11 新特性_c++ expired_t0tott的博客-CSDN博客
std::unique_ptr用法
如名字所示,unique_ptr
是个独占指针,C++ 11之前就已经存在,unique_ptr
所指的内存为自己独有,某个时刻只能有一个unique_ptr
指向一个给定的对象,不支持拷贝和赋值。下面以代码样例来说明unique_ptr
的用法,各种情况都在代码注释给出。
std::unique_ptr用法 - 简书
一、原则
使用std::unique_ptr管理具备专属所有权的资源
二、常见用法
std::unique_ptr的一个常见用法是在对象继承谱系中作为工厂函数的返回型别。这种继承谱系的工厂函数通常会在堆上分配一个对象并且返回一个指涉到它的指针,并当不在需要该对象时,由调用者负责删除之。
重置 unique_ptr 对象
C++ 智能指针 unique_ptr 详解与示例_彼此当年少,莫负好时光-CSDN博客_c++ unique_ptr
taskPtr.reset();
在 unique_ptr 对象上调用reset()
函数将重置它,即它将释放delete关联的原始指针并使unique_ptr 对象为空。
C++ 智能指针 unique_ptr 详解与示例_彼此当年少,莫负好时光-CSDN博客_c++ unique_ptr
unique_ptr 是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。
unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用。
查看下面的示例:
std::unique_ptr<PayloadDescriptor> payloadDescriptor(new PayloadDescriptor());
三、示例(以下代码需要c++14支持)
#ifndef UNIQUEPTRDEMO_H
#define UNIQUEPTRDEMO_H
#include <iostream>
#include <memory>
namespace T17_NS {
using namespace std;
/*!
* \brief The Investment class 基类
*/
class Investment
{
public:
virtual ~Investment() = default;
public:
virtual void doWork() = 0;
};
/*!
* \brief The Stock class 派生类
*/
class Stock : public Investment
{
public:
virtual void doWork() override {
cout << "Stock doWork....\n";
}
};
/*!
* \brief The Stock class 派生类
*/
class Bond : public Investment
{
public:
virtual void doWork() override {
cout << "Bond doWork....\n";
}
};
enum class InvestType {
INVEST_TYPE_STOCK,
INVEST_TYPE_BOND,
};
auto makeInvestment(InvestType type)
{
// 自定义析构器, 这里以lambda表达式的形式给出
auto delInvmt = [](Investment *pInvestment) {
// TODO 自定义析构时想干的事
cout << "delInvmt called...." << endl;
delete pInvestment;
};
// 待返回的指针, 初始化为空指针,并指定自定义析构器
// decltype(delInvmt) 用于获取自定义析构器的类型
unique_ptr<Investment, decltype(delInvmt)> pInv(nullptr, delInvmt);
// 注意这里用reset来指定pInv获取从new产生的对象的所有权, 不能用=赋值
switch (type)
{
case InvestType::INVEST_TYPE_STOCK:
//pInv = new Stock; // error!! c++11禁止从裸指针到智能指针的隐式转换
pInv.reset(new Stock);
break;
case InvestType::INVEST_TYPE_BOND:
pInv.reset(new Bond);
break;
}
// 返回智能指针
return pInv;
}
void test()
{
// 测试工厂函数
{
// pInv出作用域后会自己析构
auto pInv = makeInvestment(InvestType::INVEST_TYPE_STOCK);
if (pInv)
{
pInv->doWork();
}
}
cout << "----------------\n";
// 测试move效果
{
auto pInv = makeInvestment(InvestType::INVEST_TYPE_BOND);
auto pInv2 = move(pInv);
cout << "after move pInv to pInv2 \n";
if (!pInv)
{
cout << "pInv is empty \n";
}
if (pInv2)
{
cout << "pInv2 is valid \n";
pInv2->doWork();
}
}
cout << "----------------\n";
// 测试unique_ptr向shared_ptr转换
{
shared_ptr<Investment> pInv = makeInvestment(InvestType::INVEST_TYPE_BOND);
pInv->doWork();
}
}
} // T17_NS
#endif // UNIQUEPTRDEMO_H
为什么 C++ Primer 5 上说shared_ptr的use_count()操作可能很慢?
为什么 C++ Primer 5 上说shared_ptr的use_count()操作可能很慢? - 知乎
unique_ptr.reset() 重置指针
unique_ptr::reset - C++ Reference
智能指针是比raw 指针更智能的类,解决 dangling指针或多次删除被指向对象,以及资源泄露问题,通常用来确保指针的寿命和其指向对象的寿命一致。智能指针虽然很智能,但容易被误用,智能也是有代价的。
通常有两大类型的智能指针:独占式unique_ptr和共享式shared_ptr。这两者的区别和使用场景,更适合使用unique_ptr的场景:1.语义简单,即当你不确定使用的指针是不是被分享所有权的时候,默认选unique_ptr独占式所有权,当确定要被分享的时候可以转换成shared_ptr;2.unique_ptr效率比shared_ptr高,不需要维护引用计数和背后的控制块;3.unique_ptr用起来更顺畅,选择性更多,可以转换成shared_ptr和通过get和release定制化智能指针(custom smart pointer)。
boost::scoped_ptr<webrtc::RtpRtcp> m_rtpRtcp;
boost::scoped_ptr是一个比较简单的智能指针,它能保证在离开作用域之后它所管理对象能被自动释放。下面这个例子将介绍它的使用:
{
boost::scoped_ptr<Book> myBook(new Book());
}
[C++] Boost智能指针——boost::shared_ptr(使用及原理分析
[C++] Boost智能指针——boost::shared_ptr(使用及原理分析)_dxmcu的专栏-CSDN博客_boost::shared_ptr reset