智能指针通过自动管理内存防止泄漏,主要包括shared_ptr、unique_ptr和weak_ptr;shared_ptr用于共享所有权并自动释放资源,但需避免循环引用;unique_ptr确保独占所有权,支持所有权转移但不可复制;weak_ptr用于打破循环引用,观察shared_ptr管理的对象;在性能敏感、与C互操作或嵌入式场景中可考虑原始指针;还可通过自定义删除器管理特殊资源如文件句柄。

智能指针本质上是为了更安全地管理C++中的动态内存分配。它们通过自动释放不再需要的内存来防止内存泄漏,并简化了资源管理。
shared_ptr、unique_ptr和weak_ptr是C++标准库提供的三种主要智能指针类型,每种类型都有不同的用途和所有权模型。
shared_ptr:允许多个指针指向同一个对象,并使用引用计数来跟踪有多少个shared_ptr指向该对象。当最后一个shared_ptr被销毁时,对象会被自动删除。 unique_ptr:提供对对象的独占所有权。一次只能有一个unique_ptr指向一个对象,当unique_ptr被销毁时,对象会被自动删除。 weak_ptr:不增加对象的引用计数,而是提供对shared_ptr所管理对象的非拥有访问。weak_ptr可以用来检测对象是否仍然存在。
shared_ptr适用于多个对象需要共享同一个资源的情况。例如,多个对象需要访问同一个数据库连接或同一个文件句柄。
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass(int value) : value_(value) {
std::cout << "MyClass constructor, value: " << value_ << std::endl;
}
~MyClass() {
std::cout << "MyClass destructor, value: " << value_ << std::endl;
}
int getValue() const { return value_; }
private:
int value_;
};
int main() {
// 创建一个 shared_ptr 指向 MyClass 对象
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(10);
std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl; // 输出 1
// 复制 shared_ptr
std::shared_ptr<MyClass> ptr2 = ptr1;
std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl; // 输出 2
std::cout << "ptr2 use_count: " << ptr2.use_count() << std::endl; // 输出 2
// ptr1 和 ptr2 指向同一个对象
std::cout << "ptr1 value: " << ptr1->getValue() << std::endl;
std::cout << "ptr2 value: " << ptr2->getValue() << std::endl;
// 当 ptr1 和 ptr2 都超出作用域时,MyClass 对象才会被销毁
return 0;
}注意事项:
立即学习“C++免费学习笔记(深入)”;
make_shared
new
std::make_shared
shared_ptr
make_shared
unique_ptr适用于需要确保只有一个指针指向对象的情况。例如,表示文件句柄或网络连接等独占资源。
#include <iostream>
#include <memory>
class Resource {
public:
Resource(std::string name) : name_(name) {
std::cout << "Resource " << name_ << " acquired." << std::endl;
}
~Resource() {
std::cout << "Resource " << name_ << " released." << std::endl;
}
std::string getName() const { return name_; }
private:
std::string name_;
};
int main() {
// 创建一个 unique_ptr 指向 Resource 对象
std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>("File.txt");
// 所有权转移:ptr1 的所有权转移到 ptr2
std::unique_ptr<Resource> ptr2 = std::move(ptr1);
// ptr1 现在为空
if (ptr1 == nullptr) {
std::cout << "ptr1 is now null." << std::endl;
}
// ptr2 拥有 Resource 对象
std::cout << "ptr2 owns resource: " << ptr2->getName() << std::endl;
// 当 ptr2 超出作用域时,Resource 对象会被自动释放
return 0;
}所有权转移:
std::move
使用限制:
std::unique_ptr<int[]>
weak_ptr用于观察shared_ptr所管理的对象,但不增加对象的引用计数。它可以用来检测对象是否仍然存在,并避免循环引用。
#include <iostream>
#include <memory>
class B; // 前向声明
class A {
public:
std::shared_ptr<B> b_ptr;
~A() { std::cout << "A is destroyed" << std::endl; }
};
class B {
public:
std::weak_ptr<A> a_ptr; // 使用 weak_ptr 打破循环引用
~B() { std::cout << "B is destroyed" << std::endl; }
};
int main() {
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();
a->b_ptr = b;
b->a_ptr = a; // b 观察 a,但不拥有 a
// 当 a 和 b 超出作用域时,它们都会被销毁,不会发生内存泄漏
return 0;
}如何解决循环引用:
lock()
lock()
尽管智能指针提供了许多好处,但在某些情况下,使用原始指针可能更合适。
智能指针可以使用自定义删除器来管理特殊资源,例如文件句柄或网络连接。
#include <iostream>
#include <memory>
#include <fstream>
// 自定义删除器,用于关闭文件
struct FileDeleter {
void operator()(std::ofstream* file) {
if (file->is_open()) {
file->close();
std::cout << "File closed." << std::endl;
}
delete file;
}
};
int main() {
// 创建一个 shared_ptr,并使用自定义删除器
std::shared_ptr<std::ofstream> file(new std::ofstream("example.txt"), FileDeleter());
// 检查文件是否成功打开
if (file->is_open()) {
*file << "Hello, world!" << std::endl;
} else {
std::cerr << "Unable to open file." << std::endl;
}
// 当 file 超出作用域时,FileDeleter 会被调用,文件会被关闭
return 0;
}如何使用自定义删除器:
智能指针是C++中管理动态分配对象的重要工具。理解不同类型智能指针的特性和使用场景,可以帮助你编写更安全、更高效的代码。
以上就是C++如何使用智能指针管理动态分配对象的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号