实现一个简单的shared_ptr需要考虑以下几个方面:
1.计数器实现:将指针的计数器放在一个自定义类中,当有多个shared_ptr指向同一个对象时,计数器加1;当一个指针被销毁时,计数器减1;当计数器为0时,释放对象所占用的内存。
2.拷贝构造函数和赋值运算符实现:在拷贝构造函数和赋值运算符中,需要将新对象的计数器指向原对象的计数器,使得两个对象指向同一个计数器。同时,需要保证原计数器的值加1,新计数器的值等于原计数器的值。
以下是实现shared_ptr的示例代码:
template<typename T>
class shared_ptr {
public:
// 构造函数
shared_ptr(T* ptr = nullptr) {
if (ptr) {
data = new Counter(ptr);
}
}
// 拷贝构造函数
shared_ptr(const shared_ptr<T>& ptr) {
data = ptr.data;
if (data) {
data->counter++;
}
}
// 赋值运算符
shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
if (this != &ptr) {
release();
data = ptr.data;
if (data) {
data->counter++;
}
}
return *this;
}
// 重载*运算符
T& operator*() const {
return *(data->ptr);
}
// 重载->运算符
T* operator->() const {
return data->ptr;
}
// 获取计数器
int use_count() const {
if (data) {
return data->counter;
} else {
return 0;
}
}
// 释放指针,如果计数器为0,则删除对象
void release() {
if (data) {
data->counter--;
if (data->counter == 0) {
delete data;
}
}
data = nullptr;
}
// 析构函数
~shared_ptr() {
release();
}
private:
struct Counter {
Counter(T* p = nullptr) : ptr(p), counter(1) {}
~Counter() { delete ptr; }
T* ptr;
int counter;
};
Counter* data;
};
示例1:使用shared_ptr共享指针
#include <iostream>
#include "shared_ptr.h"
class MyClass {
public:
MyClass() { std::cout << "MyClass()" << std::endl; }
~MyClass() { std::cout << "~MyClass()" << std::endl; }
};
int main() {
shared_ptr<MyClass> p1(new MyClass); // 创建p1
shared_ptr<MyClass> p2(p1); // 复制构造函数,p1、p2计数器都为2
std::cout << "p1 use_count: " << p1.use_count() << std::endl;
std::cout << "p2 use_count: " << p2.use_count() << std::endl;
shared_ptr<MyClass> p3 = p1; // 赋值运算符,p1、p2、p3计数器都为3
std::cout << "p1 use_count: " << p1.use_count() << std::endl;
std::cout << "p2 use_count: " << p2.use_count() << std::endl;
std::cout << "p3 use_count: " << p3.use_count() << std::endl;
return 0; // 离开作用域,p1、p2、p3计数器都为0,MyClass会被自动释放
}
输出:
MyClass()
p1 use_count: 2
p2 use_count: 2
p1 use_count: 3
p2 use_count: 3
p3 use_count: 3
~MyClass()
示例2:shared_ptr数组
#include <iostream>
#include "shared_ptr.h"
class MyClass {
public:
MyClass(int n) : data(new int[n]) { std::cout << "MyClass()" << std::endl; }
~MyClass() { delete[] data; std::cout << "~MyClass()" << std::endl; }
int* data;
};
int main() {
shared_ptr<MyClass[]> p1(new MyClass[3](5)); // 创建包含3个MyClass对象的数组
std::cout << "p1[1].data[2]: " << p1[1].data[2] << std::endl; // 访问数组
return 0; // 离开作用域,MyClass数组会被自动释放
}
输出:
MyClass()
MyClass()
MyClass()
p1[1].data[2]: 5
~MyClass()
~MyClass()
~MyClass()
这里需要注意的是,shared_ptr的数组版本需要将单个类型的模板参数改为数组类型的模板参数,然后通过重载下标运算符来访问数组元素。同时,数组需要使用new[]开辟空间,使用delete[]释放空间。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++简单实现shared_ptr的代码 - Python技术站