C++智能指针学习
01.理解智能指针
#include <iostream>
#include "MyObject.h"
using namespace std;
void memory_leak_example(bool condition) {
std::cout << "\n--- Running Memory Leak Example ---" << std::endl;
MyObject* ptr = new MyObject(1);
ptr->pointer_example();
delete ptr;
std::cout << "--- Memory Leak Example Finished ---\n" << std::endl;
}
int main() {
memory_leak_example(true);
std::cout << "After memory_leak_example(true), the object was never destroyed." << std::endl;
memory_leak_example(false);
return 0;
}
02.unique_ptr
#include "MyObject.h"
#include <memory>
#include <vector>
void unique_ptr_basic_example(bool condition) {
std::cout << "\n--- Running unique_ptr Basic Example ---" << std::endl;
auto ptr = std::make_unique<MyObject >(3);
if (condition) {
std::cout << "Condition is true, returning early..." << std::endl;
return;
}
ptr->do_something();
std::cout << "No need to manually call delete!" << std::endl;
}
int main() {
unique_ptr_basic_example(true);
unique_ptr_basic_example(false);
return 0;
}
03.所有权转移
#include <iostream>
#include "MyObject.h"
#include <vector>
using namespace std;
std::unique_ptr<MyObject> create_object(int id) {
std::cout << "Factory creating an object..." << std::endl;
return std::make_unique<MyObject>(id);
}
void unique_ptr_ownership_example() {
std::cout << "\n--- Running unique_ptr Ownership Example ---" << std::endl;
auto ptr1 = create_object(4);
std::cout << "Cannot copy a unique_ptr." << std::endl;
std::cout << "Moving ownership from ptr1 to ptr2..." << std::endl;
auto ptr2 = std::move(ptr1);
if (!ptr1) {
std::cout << "ptr1 is now nullptr." << std::endl;
}
std::cout << "ptr2 now owns the object." << std::endl;
ptr2->do_something();
std::vector<std::unique_ptr<MyObject>> object_list;
object_list.push_back(std::move(ptr2));
std::cout << "Object moved into the vector." << std::endl;
if (!ptr2) {
std::cout << "ptr2 is now nullptr after moving into vector." << std::endl;
}
}
int main() {
unique_ptr_ownership_example();
std::cout << "\nEnd of main, all objects should be destroyed now." << std::endl;
return 0;
}
04_与函数交互 (获取裸指针)
#include <iostream>
#include "MyObject.h"
#include <vector>
using namespace std;
void process_raw_pointer(MyObject* raw_ptr) {
if (raw_ptr) {
std::cout << "Processing object via raw pointer..." << std::endl;
raw_ptr->do_something();
}
delete raw_ptr;
}
void unique_ptr_raw_pointer_example() {
std::cout << "\n--- Running unique_ptr Raw Pointer Example ---" << std::endl;
auto ptr = std::make_unique<MyObject>(5);
process_raw_pointer(ptr.get());
std::cout << "After processing, unique_ptr still owns the object." << std::endl;
}
int main() {
unique_ptr_raw_pointer_example();
return 0;
}
05.shared_ptr 的基本用法与引用计数
#include <memory>
#include <vector>
#include <iostream>
#include "MyObject.h"
void shared_ptr_basic_example() {
std::cout << "\n--- Running shared_ptr Basic Example ---" << std::endl;
auto s_ptr1 = std::make_shared<MyObject>(10);
std::cout << "s_ptr1 created. Use count: " << s_ptr1.use_count() << std::endl;
{
std::cout << "Entering new scope..." << std::endl;
std::shared_ptr<MyObject> s_ptr2 = s_ptr1;
std::cout << "s_ptr2 created by copying s_ptr1. Use count: " << s_ptr1.use_count() << std::endl;
std::cout << "s_ptr2 use count is also: " << s_ptr2.use_count() << std::endl;
s_ptr2->do_something();
std::cout << "Leaving new scope..." << std::endl;
}
std::cout << "After scope, s_ptr2 is destroyed. Use count: " << s_ptr1.use_count() << std::endl;
std::cout << "--- shared_ptr Basic Example Finished ---\n" << std::endl;
std::cout << "Entering new scope..." << std::endl;
std::shared_ptr<MyObject> s_ptr2 = s_ptr1;
std::cout << "!!!s_ptr2 created by copying s_ptr1. Use count: " << s_ptr1.use_count() << std::endl;
std::cout << "!!!s_ptr2 use count is also: " << s_ptr2.use_count() << std::endl;
s_ptr2->do_something();
std::cout << "Leaving new scope..." << std::endl;
}
int main() {
shared_ptr_basic_example();
return 0;
}
06_shared_ptr 与容器和函数
#include <memory>
#include <vector>
#include <iostream>
#include "MyObject.h"
void process_shared_object(std::shared_ptr<MyObject> ptr) {
std::cout << " [Inside function] Received object. Use count: " << ptr.use_count() << std::endl;
ptr->do_something();
std::cout << " [Inside function] Function finished." << std::endl;
}
void shared_ptr_advanced_example() {
std::cout << "\n--- Running shared_ptr Advanced Example ---" << std::endl;
std::vector<std::shared_ptr<MyObject>> object_list;
auto s_ptr = std::make_shared<MyObject>(11);
std::cout << "Object created. Use count: " << s_ptr.use_count() << std::endl;
object_list.push_back(s_ptr);
std::cout << "Object pushed into vector. Use count: " << s_ptr.use_count() << std::endl;
std::cout << "Calling function..." << std::endl;
process_shared_object(s_ptr);
std::cout << "Function returned. Use count: " << s_ptr.use_count() << std::endl;
s_ptr.reset();
std::cout << "s_ptr reset. Use count: " << object_list[0].use_count() << std::endl;
std::cout << "--- shared_ptr Advanced Example Finished ---\n" << std::endl;
}
int main() {
shared_ptr_advanced_example();
return 0;
}
07_weak_ptr循环引用导致的内存泄漏
#include <memory>
#include <vector>
#include <iostream>
#include "MyObject.h"
class Son;
class Father {
public:
Father() { std::cout << "Father created." << std::endl; }
~Father() { std::cout << "Father destroyed." << std::endl; }
std::shared_ptr<Son> son_;
};
class Son {
public:
Son() { std::cout << "Son created." << std::endl; }
~Son() { std::cout << "Son destroyed." << std::endl; }
std::shared_ptr<Father> father_;
};
void circular_reference_problem() {
std::cout << "\n--- Running Circular Reference Problem ---" << std::endl;
auto father = std::make_shared<Father>();
auto son = std::make_shared<Son>();
father->son_ = son;
son->father_ = father;
std::cout << "Father use count: " << father.use_count() << std::endl;
std::cout << "Son use count: " << son.use_count() << std::endl;
std::cout << "Leaving function scope..." << std::endl;
}
int main() {
circular_reference_problem();
std::cout << "After function, objects were NOT destroyed. Memory leak!" << std::endl;
return 0;
}
08_weak_ptr 打破循环引用
#include <memory>
#include <vector>
#include <iostream>
#include "MyObject.h"
class SonFixed;
class FatherFixed {
public:
FatherFixed() { std::cout << "FatherFixed created." << std::endl; }
~FatherFixed() { std::cout << "FatherFixed destroyed." << std::endl; }
std::shared_ptr<SonFixed> son_;
};
class SonFixed {
public:
SonFixed() { std::cout << "SonFixed created." << std::endl; }
~SonFixed() { std::cout << "SonFixed destroyed." << std::endl; }
std::weak_ptr<FatherFixed> father_;
};
void circular_reference_solution() {
std::cout << "\n--- Running Circular Reference Solution ---" << std::endl;
auto father = std::make_shared<FatherFixed>();
auto son = std::make_shared<SonFixed>();
father->son_ = son;
son->father_ = father;
std::cout << "Father use count: " << father.use_count() << std::endl;
std::cout << "Son use count: " << son.use_count() << std::endl;
if (!son->father_.expired()) {
std::shared_ptr<FatherFixed> father_sptr = son->father_.lock();
if (father_sptr) {
std::cout << "Son can access Father. Father use count temporarily becomes: " << father_sptr.use_count() << std::endl;
}
}
std::cout << "Leaving function scope..." << std::endl;
}
int main() {
circular_reference_solution();
std::cout << "After function, objects were correctly destroyed." << std::endl;
return 0;
}
09_使用 unique_ptr 管理 FILE
#include <cstdio>
#include <memory>
#include <iostream>
void file_closer(FILE* file) {
if (file) {
std::cout << "Custom deleter: Closing file." << std::endl;
fclose(file);
}
}
using FileUniquePtr = std::unique_ptr<FILE, decltype(&file_closer)>;
void unique_ptr_deleter_example() {
std::cout << "\n--- unique_ptr Custom Deleter Example ---" << std::endl;
FILE* raw_file_ptr = fopen("test.txt", "w");
if (!raw_file_ptr) return;
FileUniquePtr file_ptr(raw_file_ptr, &file_closer);
fprintf(file_ptr.get(), "Hello from unique_ptr with a custom deleter!\n");
std::cout << "Function scope is ending, file will be closed automatically." << std::endl;
}
int main() {
unique_ptr_deleter_example();
return 0;
}
10shared_ptr 和 Lambda 实现自定义删除器
#include <memory>
#include <iostream>
struct ThirdPartyResource {
ThirdPartyResource(int id) : id_(id) { std::cout << "Resource " << id_ << " acquired." << std::endl; }
int id_;
};
void release_third_party_resource(ThirdPartyResource* res) {
std::cout << "Custom C-style release function called for resource " << res->id_ << "." << std::endl;
delete res;
}
void shared_ptr_deleter_example() {
std::cout << "\n--- shared_ptr Custom Deleter Example ---" << std::endl;
std::shared_ptr<ThirdPartyResource> res_ptr(
new ThirdPartyResource(101),
[](ThirdPartyResource* r) {
std::cout << "Custom lambda deleter called for resource " << r->id_ << "." << std::endl;
delete r;
}
);
std::shared_ptr<ThirdPartyResource> res_ptr2(new ThirdPartyResource(102), &release_third_party_resource);
std::cout << "Function scope is ending, resources will be released." << std::endl;
}
int main() {
shared_ptr_deleter_example();
return 0;
}
11_this 指针共享
#include <memory>
#include <iostream>
#include <vector>
class GameObject : public std::enable_shared_from_this<GameObject> {
public:
GameObject() { std::cout << "GameObject created." << std::endl; }
~GameObject() { std::cout << "GameObject destroyed." << std::endl; }
std::shared_ptr<GameObject> get_shared_ptr() {
return shared_from_this();
}
void add_to_manager() {
get_game_manager().push_back(get_shared_ptr());
}
private:
static std::vector<std::shared_ptr<GameObject>>& get_game_manager() {
static std::vector<std::shared_ptr<GameObject>> manager;
return manager;
}
};
void enable_shared_from_this_example() {
std::cout << "\n--- enable_shared_from_this Example ---" << std::endl;
auto obj1 = std::make_shared<GameObject>();
obj1->add_to_manager();
std::cout << "After registration, obj1 use count: " << obj1.use_count() << std::endl;
GameObject raw_obj;
try {
}
catch (const std::bad_weak_ptr& e) {
std::cout << "Caught expected exception: " << e.what() << std::endl;
}
std::cout << "Function scope is ending..." << std::endl;
}
int main() {
enable_shared_from_this_example();
return 0;
}
12shared_ptr 和 Lambda 实现自定义删除器
#include <memory>
#include <iostream>
struct ThirdPartyResource {
ThirdPartyResource(int id) : id_(id) { std::cout << "Resource " << id_ << " acquired." << std::endl; }
int id_;
};
void release_third_party_resource(ThirdPartyResource* res) {
std::cout << "Custom C-style release function called for resource " << res->id_ << "." << std::endl;
delete res;
}
void shared_ptr_deleter_example() {
std::cout << "\n--- shared_ptr Custom Deleter Example ---" << std::endl;
std::shared_ptr<ThirdPartyResource> res_ptr(
new ThirdPartyResource(101),
[](ThirdPartyResource* r) {
std::cout << "Custom lambda deleter called for resource " << r->id_ << "." << std::endl;
delete r;
}
);
std::shared_ptr<ThirdPartyResource> res_ptr2(new ThirdPartyResource(102), &release_third_party_resource);
std::cout << "Function scope is ending, resources will be released." << std::endl;
}
int main() {
shared_ptr_deleter_example();
return 0;
}