面试题答案
一键面试- 场景一:对象存在于栈上且函数未结束
- 场景描述:当一个对象是在函数内部以自动变量(栈上变量)的形式定义时,只有当函数执行完毕,该对象的析构函数才会被调用。例如:
void someFunction() { SomeClass obj; // 这里obj的析构函数不会立即调用 // 直到函数someFunction执行结束 }
- 原理:栈上对象的生命周期与它所在的作用域相关。在函数执行过程中,栈空间会根据函数的调用和返回进行管理。当函数开始时,为局部变量分配栈空间,当函数结束时,释放这些栈空间,同时调用栈上对象的析构函数来清理资源。
- 场景二:对象存在于堆上且未释放
- 场景描述:通过
new
关键字在堆上创建的对象,如果没有显式地调用delete
,析构函数不会被调用。例如:
void anotherFunction() { SomeClass* ptr = new SomeClass(); // 这里如果不写delete ptr;,ptr指向对象的析构函数不会调用 }
- 原理:
new
操作符分配堆内存并调用构造函数初始化对象,而delete
操作符负责释放堆内存并调用析构函数清理对象。因为堆内存的管理由程序员手动控制,所以不调用delete
就不会触发析构函数。这可能会导致内存泄漏,因为对象占用的堆内存无法被回收。
- 场景描述:通过
- 场景三:使用智能指针且引用计数未归零
- 场景描述:当使用
std::shared_ptr
等智能指针管理对象时,如果对象的引用计数没有降为零,析构函数不会立即调用。例如:
void smartPtrFunction() { std::shared_ptr<SomeClass> ptr1 = std::make_shared<SomeClass>(); std::shared_ptr<SomeClass> ptr2 = ptr1; // 此时ptr1和ptr2都指向同一个对象,引用计数为2 // 当ptr1离开作用域,引用计数减为1,对象析构函数不会调用 // 直到ptr2也离开作用域,引用计数变为0,对象析构函数才会调用 }
- 原理:
std::shared_ptr
使用引用计数来管理对象的生命周期。每当一个std::shared_ptr
指向对象时,引用计数增加,当std::shared_ptr
被销毁(例如离开作用域)时,引用计数减少。只有当引用计数降为零时,才会自动调用对象的析构函数并释放对象占用的内存。
- 场景描述:当使用