【C++】const和shared_ptr的搭配使用

本文详细解释了C++中的std::shared_ptr的不同const版本,如底层const和顶层const的区别,以及它们在指针和对象修改上的限制,通过示例展示了如何正确使用这些const特性。
摘要由CSDN通过智能技术生成

1. const std::shared_ptr<T>

是底层const,指针ptr的指向不能被改变,但是ptr指向的对象可以改变

对应 T* const ptr

2. std::shared_ptr<const T>

是顶层const,指针ptr的指向可以被改变,但ptr指向的对象不能改变,只能调用不改变成员变量的const函数。

对应 const T* ptr

3. 例子

#include <iostream>
#include <memory>

class TypeA {
public:
	TypeA(float score) {
	  score_ = score;
	};
	~TypeA(){};
	void set_score(float score) {
		score_ = score;
	}
	void print_score() const { // 需要定义为const成员函数, 否则std::shared_ptr<const T>无法调用
		std::cout << "score:" << score_ << std::endl;
	}
private:
	float score_ = 0.f;
};

void FuncA(const std::shared_ptr<TypeA>& src, float score) {
	src->set_score(score); // 正确,const std::shared_ptr指向对象可以被正常修改
}

void FuncB(std::shared_ptr<const TypeA>& src, float score) {
	src->set_score(score); // 错误,std::shared_ptr<const T>指向对象不能被修改
}

int main() 
{
  auto foo_a = std::make_shared<TypeA>(80.5);
  foo_a->print_score();
  FuncA(foo_a, 90.5);
  std::shared_ptr<const TypeA> foo_b = std::make_shared<TypeA>(82.5);
  foo_b->print_score(); // 正常,只调用不改变成员变量的const函数
  FuncB(foo_b, 91.5); // 报错,调用了改变成员变量的非const函数
  foo_b->print_score();
  return 0;
}

4. 总结

shared_ptr<T> p;             ---> T * p;                                    : nothing is const
const shared_ptr<T> p;       ---> T * const p;                              : p is const
shared_ptr<const T> p;       ---> const T * p;       <=> T const * p;       : *p is const
const shared_ptr<const T> p; ---> const T * const p; <=> T const * const p; : p and *p are const.

【引用】

  1. https://cloud.tencent.com/developer/ask/sof/119171
shared_ptrC++中用于动态内存管理的智能指针之一。它能够记录对象被引用的次数,主要用于管理动态创建的对象的销毁。使用shared_ptr可以避免内存泄漏和悬挂指针等问题。 在C++中,实现shared_ptr通常需要以下几个步骤: 1. 定义一个模板类,例如SHARED_ptr,该类将作为智能指针使用。 2. 在SHARED_ptr类中,定义一个指针成员变量ptr,用于指向实际的对象。 3. 在SHARED_ptr类中,定义一个计数器类的指针成员变量refcount,用于记录对象被引用的次数。 4. 在SHARED_ptr类中,实现构造函数,用于初始化指针和计数器。 5. 在SHARED_ptr类中,实现拷贝构造函数和赋值操作符重载,用于处理多个智能指针共享同一对象的情况。 6. 在SHARED_ptr类中,实现析构函数,用于释放对象的内存空间。 7. 在SHARED_ptr类中,实现箭头运算符重载和解引用运算符重载,用于访问对象的成员函数和数据。 8. 在SHARED_ptr类外部,实现计数器类RefCount,用于记录对象被引用的次数,并在引用次数为0时释放对象的内存空间。 实现shared_ptr的详细代码如下所示: ```cpp template <class T> class SHARED_ptr { private: T* ptr; // 用来指向堆区对象 RefCount<T>* refcount; // 指向计数器对象的指针 public: SHARED_ptr(T* p) : ptr(p), refcount(new RefCount<T>()) { refcount->increment(); } SHARED_ptr(const SHARED_ptr<T>& other) : ptr(other.ptr), refcount(other.refcount) { refcount->increment(); } ~SHARED_ptr() { if (refcount->decrement() == 0) { delete ptr; delete refcount; } } T* operator->() const { return ptr; } T& operator*() const { return *ptr; } SHARED_ptr& operator=(const SHARED_ptr<T>& other) { if (this != &other) { if (refcount->decrement() == 0) { delete ptr; delete refcount; } ptr = other.ptr; refcount = other.refcount; refcount->increment(); } return *this; } }; ``` 以上是一个简单的C++实现shared_ptr的示例代码。通过使用shared_ptr,我们可以方便地管理动态创建的对象的生命周期,并避免内存泄漏和悬挂指针等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值