智能指针的缺点
智能指针是一种用于管理动态内存的工具,它可以自动化内存的分配和释放,从而减少程序员手动管理内存的出错可能性。然而,智能指针也有一些缺点,包括以下几点:
1.性能开销:智能指针需要进行额外的内存管理和引用计数操作,这可能会导致程序的性能下降。相比于原始指针,智能指针需要更多的计算资源和时间来完成内存管理任务。
2.循环引用:如果智能指针被用于管理对象之间的循环引用,就可能会出现内存泄漏的问题。当两个对象相互引用时,它们的引用计数永远不会达到零,因此它们的内存也永远不会被释放。
3.难以调试:由于智能指针管理的内存是自动分配和释放的,因此在程序运行时,很难确定哪个指针指向哪个内存块,以及哪个指针可能导致内存泄漏或悬挂指针等问题。这使得调试非常困难。
4.不适用于某些场景:智能指针通常适用于单线程环境,但在某些多线程或异步环境中,智能指针的使用可能会导致竞态条件或死锁等问题。此外,智能指针也不适用于需要在不同的进程之间共享内存的场景。
综上所述,智能指针虽然在某些情况下可以减少内存管理的工作量,但它也有一些缺点,需要根据具体的应用场景进行选择。
#include<iostream>
#include<memory>
using namespace std;
struct Test
{
shared_ptr<Test>getSharedPtr()
{
return shared_ptr<Test>(this);
}
~Test()
{
cout<<"析构函数"<<endl;
}
};
int main()
{
shared_ptr<Test> sp1(new Test);
cout<<"引用个数"<<sp1.use_count()<<endl;
shared_ptr<Test> sp2 = sp1->use_count()<<endl;
cout<<"引用个数"<<sp1.use_count()<<endl;
return 0;
}
//引用个数:1
//引用个数:1
//析构函数
//析构函数
通过输出的结果可以看到一个对象被析构了两次,其原因是这样的:在这个例子中使用同一个指针this构造了两个智能指针对象sp1和sp2,这二者之间是没有任何关系的,因为sp2并不是通过sp1初始化得到实例对象。在离开作用域之后this 将被构造的两个智能指针所各自析构,导致重复析构的错误。
#include<iostream>
#include<memory>
using namespace std;
struct Test
{
shared_ptr<Test>getSharedPtr()
{
return shared_ptr<Test>(this);
}
~Test()
{
cout<<"析构函数"<<endl;
}
};
int main()
{
shared_ptr<Test> sp1(new Test);
cout<<"引用个数"<<sp1.use_count()<<endl;
shared_ptr<Test> sp2 = sp1;
cout<<"引用个数"<<sp1.use_count()<<endl;
return 0;
}
//引用个数:1
//引用个数:2
//析构函数
循环引用问题
#include<iostream>
#include<memory>
using namespace std;
class A;
class B;
classA
{
public:
shared_ptr<B> bptr;
~A()
{
cout<<"class TA is disstruct..."<<endl;
}
};
class B
{
public:
shared_ptr<A> aptr;
~B()
{
cout<<"class TB is disstruct..."<<endl;
}
void testPtr()
{
shared_ptr<A> ap(new A);
shared_ptr<B> bp(new B);
cout<<"A的 引用计数:"<<ap.use_count()<<endl;
cout<<"B的 引用计数:"<<bp.use_count()<<endl;
}
}
int main()
{
testPtr();
return 0;
}
A的引用计数:1
B的引用计数:1
A的引用计数:2
B的引用计数:2
共享智能指针ap,bp对A,B实例对象的引用计数变为2,在共享智能指针离开作用域之后引用计数只能减为1,这种情况下不会去删除智能指针管理内存,导致类A,B的实例对象不能被析构,最终造成内存泄漏。通过使用weak_ptr可以解决这个问题,只需要将类A或者类B的任意一个成员改为weak_ptr.
class A
{
public:
weak_ptr<B>bptr;
~A()
{
cout<<"A的析构函数"<<endl;
}
};
class B
{
public:
shared_ptr<A> aptr;
~B()
{
cout<<"B的析构函数"<<endl;
}
};
void testPtr()
{
shared_ptr<A> ap(new A);
shared_ptr<B> bp(new B);
cout<<"A 的引用计数:"<<ap.use_count()<<endl;
cout<<"B 的引用计数:"<<bp.use_count()<<endl;
ap->bptr = bp;
bp->aptr = ap;
cout<<"A 的引用计数:"<<ap.use_count()<<endl;
cout<<"B 的引用计数:"<<bp.use_count()<<endl;
}