欢迎访问我的博客首页。
4.共享指针的实现
template <typename T>
class Shared_ptr {
public:
// 1.无参构造函数。
Shared_ptr() :m_ptr(nullptr), m_count(new size_t(0)) {}
// 2.有参构造函数(裸指针)。
Shared_ptr(T* ptr) :m_ptr(ptr), m_count(new size_t(1)){}
// 3.拷贝构造函数(浅拷贝)。
Shared_ptr(const Shared_ptr& ptr) :m_ptr(ptr.m_ptr), m_count(ptr.m_count) {
if (m_ptr != nullptr) // 用m_ptr=nullptr的智能指针初始化另一智能指针,计数器不应改变。
(*m_count)++; // 改变*m_count没有改变m_count所以形参为const。
}
// 4.移动构造函数。
Shared_ptr(Shared_ptr&& ptr) :m_ptr(ptr.m_ptr), m_count(ptr.m_count) {
ptr.set_ptr(nullptr);
ptr.set_count(nullptr);
}
// 5.移动赋值运算符重载。
Shared_ptr& operator=(Shared_ptr&& ptr) {
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
ptr.set_ptr(nullptr);
ptr.set_count(nullptr);
return *this;
}
// 6.赋值运算符重载(浅拷贝)。
Shared_ptr& operator=(const Shared_ptr& ptr) {
if (this == &ptr)
return *this;
// 与所指对象切断连系。
if (m_ptr != nullptr) {
(*m_count) -= 1;
if (*m_count == 0) {
delete m_ptr;
m_ptr = nullptr;
m_count = nullptr;
}
}
// 与新对象建立连系。
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
if (m_ptr!= nullptr) // 用m_ptr=nullptr的智能指针初始化另一智能指针,计数器不应改变。
(*m_count) += 1;
return *this;
}
// 7.重载操作符:判断是否为0、NULL。
bool operator==(const int b) { return (m_ptr == 0) ^ b; }
bool operator!=(const int b) { return !((m_ptr == 0) ^ b); }
// 7.重载操作符:判断是否为nullptr。
bool operator==(const nullptr_t& b) { return m_ptr == b; }
bool operator!=(const nullptr_t& b) { return m_ptr != b; }
// 7.重载布尔值操作符:if(x)判断是否为空指针。
operator bool() { return m_ptr == nullptr; }
T* get() { return m_ptr; } // 8.获取裸指针。
T* operator->() { return m_ptr; } // 9.箭头运算符:获取裸指针所指对象的成员。
T& operator*() { return *m_ptr; } // 10.解引用运算符:获取裸指针所指对象。
bool unique() { return *m_count == 1; } // 11.是否独占对象。
size_t use_count() { return m_count ? *m_count: 0; } // 12.获取共享数量。
void swap(Shared_ptr& ptr) { std::swap(*this, ptr); } // 13.交换两个智能指针。
// 14.析构函数。
~Shared_ptr() {
if (m_count != nullptr) { // 移动构造函数和移动赋值会把两个成员指针置空。
if (*m_count > 0)
(*m_count)--;
if (*m_count == 0) {
delete m_ptr;
m_ptr = nullptr;
m_count = nullptr;
}
}
}
private:
void set_ptr(T* m_ptr) { this->m_ptr = m_ptr; }
void set_count(size_t* m_count) { this->m_count = m_count; }
private:
T* m_ptr;
size_t* m_count;
};
template<typename T, typename... Args>
Shared_ptr<T> Make_shared(Args&&... args) { // 返回值不能是引用类型。
Shared_ptr<T> s_ptr(new T(std::forward<Args>(args)...));
return s_ptr;
}