1.需要设计
智能指针实现,目标用一个对象管理指针。
指针类:B
智能指针类A<T>
A<B> a(new B);
用A来管理B的指针,如果有多个指针指向一个对象,那么都用A来承载这个指针
A<B> b(a);
这里需要一个拷贝构造函数,为什么不用赋值运算符的,两个智能指针赋值将不会有任何价值,所以重载赋值运算符没有任何意义,这里通过拷贝构造函数来实现一个新的指针的产生。
经历上面的智能指针拷贝构造后,会产生多个指针指向同一个对象的情况,如果一个对象删除了,就会出现指针悬垂的情况。这里添加一个delet_c函数来控制指针的删除,另外因为智能指针对象的创建是创建在栈上,为了借用堆对象析构时候对指针的控制,这里在析构函数也做了控制,这里为了模拟对象析构的过程,也用一个函数模拟了"delete 指针"的行为。
2.代码
#include <iostream>
using namespace std;namespace T1 {//智能运算符重载,智能指针的基础class B{public:void fun() {cout << "fun\n";}};template<class T>class A{public:void set(T* t) {this->t = t;}/// <summary>/// 重载运算符,智能指针的基础/// </summary>/// <returns></returns>T* operator->() {return t;}T* t;};void main() {A<B> pa;pa.set(new B());pa->fun();}
}
namespace T2 {//用构造函数和析构函数控制指针的生命周期class B{public:void fun() {cout << "fun\n";}};template<class T>class A{public:/// <summary>/// 用构造函数控制指针的生命周期/// </summary>/// <param name="t"></param>A(T* t) {this->t = t;}/// <summary>/// 析构函数,释放奶茶/// </summary>~A() {delete t;}T* operator->() {return t;}T* t;};void main() {A<B> pa(new B());pa->fun();}
}
namespace T3 {class B{public:void fun() {cout << "fun\n";}};template<class T>class A{public:A(T* t) {this->t = t;//创建一个堆中的内存tsum = new int(0);}/// <summary>/// 用拷贝构造函数,控制指针被拷贝的次数/// </summary>/// <param name="object"></param>A(const A<T>& object) {this->t = object.t;this->tsum = object.tsum;(*tsum)++;}~A() {//如果之前进行过指针的释放了,那么这里不需要释放了if (isdelet) {return;}delete t;}T* operator->() {return t;}T* t;int* tsum;void delete_t() {//t == NULL:防止以外的delete//isdelet==true:一个指针如果释放过一次,就不需要再次释放了if (t == NULL|| isdelet==true) {return;}//执行过指针释放了,那么析构函数的时候就不需要释放指针了isdelet = true;if (*tsum > 0) {(*tsum)--;}else{delete t;t == NULL;}}private://释放释放过bool isdelet = false;//对于单纯的指针,赋值没有任何意义A& operator =(const A& a) = delete;/*A& operator =(const A& a) {//t = a.t;return *this;}*/};void main() {A<B> pa(new B());A<B> pb(pa);//A<B> pc(pb);pa->fun();//pa = pb;pa.delete_t();pb.delete_t();}
}
int main()
{//T1::main();//T2::main();T3::main();cout << "Hello World!\n";
}
3.运行结果
fun
Hello World!