智能指针类 sp:
这是一个模板类,可以管理任何类型 T 的指针
主要功能包括:
通过工厂方法 make() 创建对象并返回智能指针
禁用拷贝构造和赋值(避免多个智能指针管理同一对象)
支持移动语义(通过移动构造和移动赋值)
提供指针操作符重载(-> 和 *)
自动管理内存(析构时自动释放)
被管理对象类 MyObject:
一个简单的测试类,包含构造/析构函数和一些成员函数
用于演示智能指针如何管理对象生命周期
main函数中的演示:
创建智能指针管理的对象
访问对象成员函数
测试移动语义(将 obj2 移动给 obj3)
获取原始指针并访问对象
关键特性:
使用 std::forward 实现完美转发
通过删除拷贝构造/赋值避免浅拷贝问题
移动语义确保资源所有权的正确转移
析构时自动释放内存,防止内存泄漏
这个实现类似于 C++11 中的 std::unique_ptr,但更加简化.
#include <iostream>
#include <utility> // for std::forward
// 简化版智能指针模板类
template<typename T>
class sp {
public:
// 工厂方法:创建对象并返回智能指针
template <typename... Args>
static sp<T> make(Args&&... args) {
T* t = new T(std::forward<Args>(args)...);
return sp<T>(t);
}
// 构造函数
sp(T* ptr = nullptr) : m_ptr(ptr) {
std::cout << "sp constructor: " << m_ptr << std::endl;
}
// 析构函数
~sp() {
std::cout << "sp destructor: " << m_ptr << std::endl;
delete m_ptr;
}
// 禁用拷贝构造和赋值(简化实现)
sp(const sp&) = delete;
sp& operator=(const sp&) = delete;
// 移动构造函数
sp(sp&& other) noexcept : m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
// 移动赋值运算符
sp& operator=(sp&& other) noexcept {
if (this != &other) {
delete m_ptr;
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
}
return *this;
}
// 获取原始指针
T* get() const { return m_ptr; }
// 指针操作符重载
T* operator->() const { return m_ptr; }
T& operator*() const { return *m_ptr; }
// 测试函数
void test_sp() {
std::cout << "sp::test_sp() called" << std::endl;
}
private:
T* m_ptr; // 管理的原始指针
};
// 被管理的对象类
class MyObject {
public:
MyObject(int id, const char* name)
: m_id(id), m_name(name) {
std::cout << "MyObject constructor: "
<< id << ", " << name << std::endl;
}
~MyObject() {
std::cout << "MyObject destructor: "
<< m_id << ", " << m_name << std::endl;
}
void showInfo() const {
std::cout << "Object Info: "
<< m_id << ", " << m_name << std::endl;
}
void test_MyObject() {
std::cout << "MyObject::test_MyObject() called" << std::endl;
}
private:
int m_id;
std::string m_name;
};
int main() {
// 1. 使用智能指针创建对象
sp<MyObject> obj1 = sp<MyObject>::make(1, "First Object");
// 2. 访问对象成员函数
obj1->showInfo();
obj1->test_MyObject();
// 3. 访问智能指针函数
obj1.test_sp();
// 4. 移动语义测试
{
std::cout << "\nCreating obj2..." << std::endl;
sp<MyObject> obj2 = sp<MyObject>::make(2, "Second Object");
std::cout << "Moving obj2 to obj3..." << std::endl;
sp<MyObject> obj3 = std::move(obj2);
std::cout << "After move:" << std::endl;
if (obj2.get() == nullptr) {
std::cout << "obj2 is now empty" << std::endl;
}
obj3->showInfo();
std::cout << "Leaving inner scope..." << std::endl;
}
// 5. 原始指针访问
MyObject* rawPtr = obj1.get();
rawPtr->showInfo();
std::cout << "\nMain function ending..." << std::endl;
return 0;
}