
🔥个人主页:guoguoqiang. 🔥专栏:我与C++的爱恋

文章目录
1.为什么需要智能指针
int div() {
int a, b;
cin >> a >> b;
if (b == 0)
throw invalid_argument("除0错误");
return a / b;
}
void Func() {
// 1、如果p1这里new 抛异常会如何?
// 2、如果p2这里new 抛异常会如何?
// 3、如果div调用这里又会抛异常会如何?
int* p1 = new int;
int* p2 = new int;
cout << div() << endl;
delete p1;
delete p2;
}
int main() {
try
{
Func();
}
catch (exception& e)
{
cout << e.what() << endl;
}
return 0;
}
问题分析:上面的问题分析出来我们发现有什么问题?
动态内存分配没有释放:在 Func 函数中,您使用了 new int 来动态分配内存,但是在函数结束时,您没有释放这些内存。这将导致内存泄漏,因为这些动态分配的内存块不会被释放,最终可能会耗尽系统的内存资源。
异常安全性:在 div 函数中,如果除数 b 为0,会抛出一个 invalid_argument 异常。如果这个异常被抛出,那么在 Func 函数中分配的内存(p1 和 p2)不会被释放,这同样会导致内存泄漏。
main 函数中的异常处理:在 main 函数中,您捕获了所有类型的异常,包括 invalid_argument。但是,您没有检查捕获到的异常类型,这意味着任何类型的异常都会被打印出来。这可能会掩盖其他潜在的内存泄漏问题。
int div() {
int a, b;
cin >> a >> b;
if (b == 0)
throw invalid_argument("除0错误");
int result = a / b;
return result;
}
void Func() {
int* p1 = new int;
int* p2 = new int;
try {
cout << div() << endl;
} catch (invalid_argument& e) {
cout << e.what() << endl;
delete p1;
delete p2; // 释放动态分配的内存
return; // 提前退出函数
}
delete p1;
delete p2;
}
int main() {
try {
Func();
} catch (exception& e) {
cout << e.what() << endl;
}
return 0;
}
智能指针的引入:
double Division(int a, int b)
{
// 当b == 0时抛出异常
if (b == 0)
{
throw "Division by zero condition!";
}
return (double)a / (double)b;
}
struct A
{
~A() noexcept
{
cout << "~A()" << endl;
}
int _a1 = 0;
int _a2 = 0;
};
template<class T>
class SmartPtr
{
public:
// RAII
SmartPtr(T* ptr)
:_ptr(ptr)
{
}
~SmartPtr()
{
delete _ptr;
}
// 重载运算符,模拟指针的行为
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
void Func()
{
// 更好解决方案是智能指针
shared_ptr<A> sp1(new A);
SmartPtr<A> sp2(new A);
sp1->_a1++;
sp1->_a2++;
// 智能指针麻烦的是拷贝
// SmartPtr<A> sp3(sp1);
//unique_ptr 不让拷贝
//unique_ptr<A> sp3(sp1);
//shared_ptr 支持拷贝
shared_ptr<A> sp3(sp1);
int len

最低0.47元/天 解锁文章
2650

被折叠的 条评论
为什么被折叠?



