#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Student {
public:
explicit Student(int age)
{
age_ = age;
}
void Show() const
{
cout << "age = " << age_ << endl;
}
~Student()
{
cout << "Student的析构" << endl;
}
private:
int age_;
};
template<typename T>
class AutoPtr {
public:
AutoPtr()
{
ptr_ = nullptr;
}
explicit AutoPtr(T *ptr)
{
ptr_ = ptr;
}
AutoPtr(AutoPtr &other)
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
AutoPtr &operator=(AutoPtr &other)
{
if (ptr_ != other.ptr_) {
delete ptr_;
}
ptr_ = other.ptr_;
other.ptr_ = nullptr;
return *this;
}
T &operator*()
{
return *ptr_;
}
T *operator->()
{
return ptr_;
}
~AutoPtr()
{
if (ptr_ != nullptr) {
cout << "释放内存" << endl;
delete ptr_;
ptr_ = nullptr;
}
}
private:
T *ptr_;
};
void test01()
{
// 智能指针为了实现: 不让程序自己释放动态内存,达到一种自动释放的功能
// 构造函数,对象离开作用域后会自动调用析构函数
// AutoPtr<int> ins(new int);
// *ins = 10;
// cout << *ins << endl;
Student *sp = new Student(10);
sp->Show();
AutoPtr<Student> ins2(sp);
(*ins2).Show();
// (ins2.operator->())->Show();
ins2->Show();
}
void test02()
{
auto_ptr<int> ins1(new int);
*ins1 = 10;
cout << *ins1 << endl;
auto_ptr<Student> ins2(new Student(10));
(*ins2).Show();
ins2->Show();
auto_ptr<int> ins3(new int);
// auto_ptr<int> ins4(ins3);
// *ins3 = 10;
// cout << *ins3 << endl;
// cout << *ins4 << endl;
auto_ptr<int> ins4;
ins4 = ins3;
*ins3 = 10;
cout << *ins3 << endl;
cout << *ins4 << endl;
}
void test03()
{
unique_ptr<int> ins1(new int);
*ins1 = 10;
cout << *ins1 << endl;
unique_ptr<Student> ins2(new Student(10));
(*ins2).Show();
ins2->Show();
// 将类中默认的拷贝构造和赋值运算符重载函数删除
// unique_ptr<Student> ins3(ins2);
}
template<typename T>
class UniquePtr {
public:
UniquePtr()
{
ptr_ = nullptr;
}
explicit UniquePtr(T *ptr)
{
ptr_ = ptr;
}
UniquePtr(UniquePtr &other) = delete;
UniquePtr &operator=(UniquePtr &other) = delete;
T &operator*()
{
return *ptr_;
}
T *operator->()
{
return ptr_;
}
~UniquePtr()
{
if (ptr_ != nullptr) {
cout << "释放内存" << endl;
delete ptr_;
ptr_ = nullptr;
}
}
private:
T *ptr_;
};
class City {
public:
City() = default;
City(const City &other) = delete;
City(int age)
{
}
};
void test04()
{
shared_ptr<int> ins1(new int);
*ins1 = 10;
cout << *ins1 << endl;
// 引用计数的方式来实现
shared_ptr<Student> ins2(new Student(10));
(*ins2).Show();
ins2->Show();
cout << "cnt = " << ins2.use_count() << endl; // 1
{
shared_ptr<Student> ins3(ins2);
cout << "cnt = " << ins2.use_count() << endl; // 2
cout << "cnt = " << ins3.use_count() << endl; // 2
cout << "-------------------------------" << endl;
ins3->Show();
(*ins3).Show();
}
cout << "cnt = " << ins2.use_count() << endl; // 1
(*ins2).Show();
ins2->Show();
}
template<typename T>
class SharedPtr {
public:
SharedPtr()
{
ptr_ = nullptr;
}
explicit SharedPtr(T *ptr)
{
num++;
ptr_ = ptr;
}
SharedPtr(SharedPtr &other)
{
ptr_ = other.ptr_;
num++;
}
SharedPtr &operator=(SharedPtr &other)
{
ptr_ = other.ptr;
num++;
return *this;
}
T &operator*()
{
return *ptr_;
}
T *operator->()
{
return ptr_;
}
~SharedPtr()
{
--num;
if (ptr_ != nullptr && num == 0) {
cout << "释放内存" << endl;
delete ptr_;
ptr_ = nullptr;
}
}
int use_count() const
{
return num;
}
private:
T *ptr_;
static int num;
};
template<typename T>
int SharedPtr<T>::num = 0;
void test05()
{
SharedPtr<Student> ins2(new Student(10));
cout << ins2.use_count() << endl; // 1
{
SharedPtr<Student> ins3(ins2);
cout << ins2.use_count() << endl; // 2
cout << ins3.use_count() << endl; // 2
cout << "-------------------------------" << endl;
ins3->Show();
(*ins3).Show();
}
cout << ins2.use_count() << endl; // 1
(*ins2).Show();
ins2->Show();
}
template<typename T>
class SharedPtr2 {
public:
SharedPtr2()
{
num_ = nullptr;
ptr_ = nullptr;
}
explicit SharedPtr2(T *ptr)
{
num_ = new int;
*num_ = 1;
ptr_ = ptr;
}
SharedPtr2(SharedPtr2 &other)
{
ptr_ = other.ptr_;
num_ = other.num_;
(*other.num_)++;
}
SharedPtr2 &operator=(SharedPtr2 &other)
{
ptr_ = other.ptr;
num_ = other.num_;
(*other.num_)++;
return *this;
}
T &operator*()
{
return *ptr_;
}
T *operator->()
{
return ptr_;
}
~SharedPtr2()
{
(*num_)--;
if (ptr_ != nullptr && *num_ == 0) {
cout << "释放内存" << endl;
delete ptr_;
delete num_;
ptr_ = nullptr;
num_ = nullptr;
}
}
int use_count() const
{
return *num_;
}
private:
T *ptr_;
int *num_;
};
void test06()
{
SharedPtr2<Student> ins2(new Student(10));
cout << ins2.use_count() << endl; // 1
{
SharedPtr2<Student> ins3(ins2);
cout << ins2.use_count() << endl; // 2
cout << ins3.use_count() << endl; // 2
cout << "-------------------------------" << endl;
ins3->Show();
(*ins3).Show();
}
cout << ins2.use_count() << endl; // 1
(*ins2).Show();
ins2->Show();
}
int main()
{
// test01();
// test02();
// test03();
// test04();
// test05();
test06();
return 0;
}
这段代码主要介绍了C++中智能指针的使用。智能指针是为了实现自动释放动态内存的功能而设计的。在代码中,使用了四种不同类型的智能指针:AutoPtr
、unique_ptr
、shared_ptr
和自定义的SharedPtr
。
AutoPtr
是自定义的智能指针类,实现了资源的自动释放功能。它使用了RAII(资源获取即初始化)的思想,在构造函数中获取资源,在析构函数中释放资源。unique_ptr
是C++标准库中提供的智能指针类,用于管理独占所有权的指针。它确保在其生命周期结束时自动释放所管理的资源。shared_ptr
也是C++标准库中提供的智能指针类,用于管理共享所有权的指针。它使用引用计数的方式来实现资源的管理,确保在所有共享该资源的shared_ptr
对象都被销毁后才释放资源。-
SharedPtr
是一个自定义的智能指针类,与shared_ptr
类似。智能指针是一种用于管理动态分配的内存的工具,它可以自动地进行内存的分配和释放,避免了手动管理内存的繁琐和容易出错的问题。shared_ptr
是C++标准库中提供的智能指针类,用于管理共享所有权的对象。它使用引用计数的方式来跟踪有多少个指针指向同一个对象,当没有指针指向该对象时,自动释放该对象的内存。