引用计数指针
是通过计数器记录资源的占用情况,能减少资源重复创建,达到资源高效复用的效果。当计数器到达0时,表明资源没有被引用,可以被释放。实现引用计数指针
的关键在于:
- 实现计数器
- 实现构造函数和赋值函数
- 实现析构函数
下面是实现计数器的代码:
#include <cassert>
#include <iostream>
class counter {
public:
counter() : m_count(1) {}
void add() { ++m_count; }
size_t sub() { return --m_count; }
size_t get() const { return m_count; }
private:
size_t m_count;
};
代码简单,仅是实现计数器的增、减和获取功能。
下面是实现构造函数、析构函数和帮助函数:
template <typename T> class shared_pointer {
public:
// 默认构造函数
explicit shared_pointer(T *ptr = nullptr) noexcept : m_ptr(ptr) {
m_counter = new counter();
}
// 拷贝构造函数
shared_pointer(shared_pointer &other) noexcept {
other.m_counter->add();
m_ptr = other.m_ptr;
m_counter = other.m_counter;
}
// 移动构造函数,移动资源
shared_pointer(shared_pointer &&other) noexcept {
m_ptr = other.m_ptr;
m_counter = other.m_counter;
other.m_ptr = nullptr;
other.m_counter = nullptr;
}
// 赋值,仅仅是交换资源
shared_pointer &operator=(shared_pointer &rhs) noexcept {
rhs.swap(*this);
return *this;
}
// 移动赋值,仅仅是交换资源
shared_pointer &operator=(shared_pointer &&rhs) noexcept {
rhs.swap(*this);
return *this;
}
~shared_pointer() noexcept {
if (m_counter && !m_counter->sub()) {
delete m_counter;
if (m_ptr) {
delete m_ptr;
}
}
}
size_t count() const noexcept {
if (!m_counter) return 0;
return m_counter->get();
}
void swap(shared_pointer &rhs) noexcept {
std::swap(m_ptr, rhs.m_ptr);
std::swap(m_counter, rhs.m_counter);
}
private:
T *m_ptr;
counter *m_counter;
};
template <typename T>
void swap(shared_pointer<T> &lhs, shared_pointer<T> &rhs) noexcept {
lhs.swap(rhs);
}
上面实现相关函数的功能:
-
默认构造函数:创建资源
-
拷贝构造函数:共享资源
-
移动构造函数:移动资源
-
赋值、移动赋值函数和
swap
函数: 交换资源 -
析构函数:释放资源
下面是测试代码:
int main(void) {
/* std::string *str = nullptr; */
std::string *str = new std::string{"hello world"};
// 创建资源
shared_pointer<std::string> sp_1{str};
assert(sp_1.count() == 1);
// 共享资源
shared_pointer<std::string> sp_2{sp_1};
assert(sp_1.count() == 2);
assert(sp_2.count() == 2);
// 交换资源
shared_pointer<std::string> sp_3;
sp_3 = sp_2;
assert(sp_1.count() == 2);
assert(sp_2.count() == 1);
assert(sp_3.count() == 2);
// 移动资源
shared_pointer<std::string> sp_4{std::move(sp_1)};
assert(sp_1.count() == 0);
assert(sp_2.count() == 1);
assert(sp_3.count() == 2);
assert(sp_4.count() == 2);
// 交换资源
shared_pointer<std::string> sp_5;
sp_5 = std::move(sp_4);
assert(sp_1.count() == 0);
assert(sp_2.count() == 1);
assert(sp_3.count() == 2);
assert(sp_4.count() == 1);
assert(sp_5.count() == 2);
return 0;
}
上面是引用计数指针
的简单实现,功能还是非常有限的,但作为学习智能指针
还是有不错的。