📌  相关文章
📜  是否可以显式调用构造函数和析构函数?

📅  最后修改于: 2021-05-25 21:01:34             🧑  作者: Mango

构造函数是一个特殊的成员函数,当创建对象时编译器会自动调用它,而析构函数也是一个特殊的成员函数,当对象超出范围时,编译器也会隐式调用它。当动态分配的对象被分配和销毁时,它们也被调用,new运算符分配存储并调用构造函数,delete运算符调用析构函数并释放new分配的内存。

是否可以显式调用构造函数和析构函数?
是的,程序员可以显式调用特殊的成员函数。以下程序显式调用构造函数和析构函数。

#include 
using namespace std;
  
class Test
{
public:
    Test()  { cout << "Constructor is executed\n"; }
    ~Test() { cout << "Destructor is executed\n";  }
};
  
int main()
{
    Test();  // Explicit call to constructor
    Test t;    // local object
    t.~Test(); // Explicit call to destructor
    return 0;
}

输出:

Constructor is executed
Destructor is executed
Constructor is executed
Destructor is executed
Destructor is executed 

当显式调用构造函数时,编译器将创建一个无名的临时对象,并立即将其销毁。这就是为什么输出中的第二行是对析构函数的调用。
这是我和Bjarne Stroustrup博士之间通过邮件就此主题进行的对话:

我:为什么C++允许显式调用构造函数?您不认为这不应该吗?
Bjarne博士:否。类类型的临时对象很有用。

C++标准的第12.4 / 14节指出:
一旦为一个对象调用了析构函数,该对象就不复存在了。如果为生存期已结束的对象调用析构函数,则该行为未定义。[示例:如果显式调用了自动对象的析构函数,并且随后以通常会调用对象的隐式销毁的方式保留该块,行为是不确定的。 —结束示例]。

如此处所述,我们永远不要在本地(自动)对象上显式调用析构函数,因为这样做确实会导致不良结果。

当本地对象超出范围时,它们将被编译器自动销毁,这是C++语言的保证。通常,不应显式调用特殊成员函数。
构造函数和析构函数也可以从类的成员函数中调用。请参阅以下程序:

#include 
using namespace std;
  
class Test
{
public:
    Test()  { cout << "Constructor is executed\n"; }
    ~Test() { cout << "Destructor is executed\n";  }
    void show()  {  Test();  this->Test::~Test();  }
};
  
int main()
{
    Test t;
    t.show();
    return 0;
}

输出:

Constructor is executed
Constructor is executed
Destructor is executed
Destructor is executed
Destructor is executed

仅当通过使用new放置将对象放置在内存中的特定位置时,才需要显式调用析构函数。动态分配对象时,不应显式调用析构函数,因为delete运算符自动调用析构函数。

作为练习,请预测以下程序的输出:

#include 
using namespace std;
  
class Test
{
public:
    Test()  { cout << "Constructor is executed\n"; }
    ~Test() { cout << "Destructor is executed\n";  }
    friend void fun(Test t);
};
void fun(Test t)
{
    Test();
    t.~Test();
}
int main()
{
    Test();
    Test t;
    fun(t);
    return 0;
}

资料来源:
http://www.parashift.com/c++-faq/dont-call-dtor-on-local.html
http://www.parashift.com/c++-faq/placement-new.html
http://msdn.microsoft.com/en-us/library/35xa3368.aspx

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”