当指针在 cpp 17 中失去引用时,是否会调用非默认析构函数?
Does the non default destructor be called when a pointer goes out of reference in cpp 17?
'''
Class A {
....
....
..
/// option A
~A() = default
/// option B
~A() {
///destructor code here
}
}
'''
假设我使用选项 B,其中我定义了自己的解构函数,当指针指向持有上述类的对象时,我执行类似操作
objAPtr = nullptr;
是否调用析构函数? 还是上述内容仅适用于选项 B
我在这里使用智能指针:
objAPtr = make_shared<A>();
如果你有例如
A* objAPtr = new A;
objAPtr = nullptr;
那么不,objAPtr
指向的对象不会被破坏。相反,您将丢失对该对象的唯一引用,并且它将是泄漏。
这与你拥有的析构函数的"种类"无关。
不,析构函数不会通过设置指向对象的指针来自动调用nullptr
。何时以及如何调用析构函数不仅与是否= default
声明析构函数正交,还取决于情况以及用于保存A
实例的内存的分配方式。堆栈上具有A
实例的示例:
{
A aInstance;
A *somePointerToA = &aInstance;
somePointerToA = nullptr; // aInstance not touched, only the pointer to it.
} // aInstance goes out of scope, now the destructor is called.
在堆上创建时:
auto *aInstance = new A;
a *somePointerToA = aInstance;
somePointerToA = nullptr; // aInstance again untouched.
delete aInstance; // Now the destructor is called.
当使用智能指针管理实例时,这些语义会发生变化,该指针负责销毁。例:
#include <memory>
auto aInstance = std::make_unique<A>();
aInstance = nullptr; // The std::unique_ptr calles A's destructor
auto aSharedInstance = std::make_shared<A>();
auto anotherSharedInstance = aSharedInstance;
aSharedInstance = nullptr; // dtor not called because of anotherSharedInstance
anotherSharedInstance = nullptr; // last pointer to the instance, dtor is called
是的,在将变量设置为 nullptr 或进行重置时也会调用析构函数:
class Test
{
private:
int m_nID;
public:
Test(int nID)
{
std::cout << "Constructing Test " << nID << 'n';
m_nID = nID;
}
~Test()
{
std::cout << "Destructing Test " << m_nID << 'n';
}
int getID() { return m_nID; }
};
int main()
{
// create a shared pointer
auto pTest = std::make_shared<Test>(1);
std::cout << pTest->getID() << 'n';
// Allocate a Test dynamically
auto pTest2 = std::make_shared<Test>(2);
std::cout << pTest2->getID() << 'n';
pTest = nullptr;
//pTest.reset();
std::cout << "before sleep n ";
sleep(5);
return 0;
} // Test goes out of scope here
运行上述析构函数是在将其设置为 nullptr 时调用的。
编译选项
g++ def_destr.cpp -std=c++14
相关文章:
- 返回指向对象的指针的函数调用是否为 prvalue?
- MFC 中的窗口消息管理:添加基类调用是否是强制性的?
- 在 v8 JavaScript 中重复调用C++是否有巨大的开销?
- dynamic_cast每次调用是否比具有空检查的缓存变量更昂贵?
- 对外部函数的调用是否强制从内存加载
- clang 拒绝具有尾随 decltype 返回类型的模板调用是否正确,具体取决于其重载之一?
- 构造函数的初始值设定项列表中的函数调用是否按顺序排序?
- 从 std::d eque 线程对 emplace_back() 和运算符 []() 的并发调用是否安全?
- 函数调用是否作为另一个函数参数遵循任何定义的行为
- 汇编函数调用是否会导致所有寄存器被推送到堆栈中
- 来自另一个线程的 SendMessage() 调用是否将消息发布到消息队列
- Inotify和Select调用是否可以合并
- 函数调用是否需要表达式
- 对 std 构造函数的调用是否需要限定
- 此构造函数调用是否具有特殊名称
- 将 delete 作为运算符或函数调用是否有任何区别
- 使用 COM 跨 CRT 边界调用是否安全
- 是否有一种方法可以使用SFINAE来确定对模板化函数的调用是否会由于所提供的类型而失败
- 类方法调用是否会在for循环中进行优化
- 对运算符的调用是否'delete'同步的?