关闭

构造函数和析构函数的一些问题

发表于:2012-6-21 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:luxiaoxun    来源:51Testing软件测试网采编

  1、构造函数和析构函数为什么没有返回值?

  构造函数和析构函数是两个非常特殊的函数:它们没有返回值.这与返回值为void的函数显然不同.后者虽然也不返回任何值,但还可以让它做点别的事情,而构造函数和析构函数则不允许.在程序中创建和消除一个对象的行为非常特殊,就像出生和死亡,而且总是由编译器来调用这些函数以确保它们被执行.如果它们有返回值,要么编译器必须知道如何处理返回值,要么就只能由客户程序员自己来显式的调用构造函数与析构函数,这样一来,安全性就被人破坏了。另外,析构函数不带任何参数,因为析构不需任何选项.

  如果允许构造函数有返回值,在某此情况下,会引起歧义。如下两个例子

class C
{
   public:
     C(): x_(0) {    }
     C(int i): x_(i) {   }

   private:
       int x_;
};

  如果C的构造函数可以有返回值,比如int:

  int C():x_(0) { return 1; } //1表示构造成功,0表示失败

  那么下列代码会发生什么事呢?

  C c=C(); //此时c.x_==1!!!

  很明显,C()调用了C的无参数构造函数。该构造函数返回int值1。恰好C有一个但参数构造函数C(int i)。于是,混乱来了。按照C++的规定,C c=C();是用默认构造函数创建一个临时对象,并用这个临时对象初始化c。此时,c.x_的值应该是0。但是,如果C::C()有返回值,并且返回了1(为了表示成功),则C++会用1去初始化c,即调用但参数构造函数C::C(int i)。得到的c.x_便会是1。于是,语义产生了歧义。使得C++原本已经非常复杂的语法,进一步混乱不堪。

  构造函数的调用之所以不设返回值,是因为构造函数的特殊性决定的。从基本语义角度来讲,构造函数返回的应当是所构造的对象。否则,我们将无法使用临时对象:

  void f(int a) {...}      //(1)

  void f(const C& a) {...} //(2)

  f(C()); //(3),究竟调用谁?

  对于(3),我们希望调用的是(2),但如果C::C()有int类型的返回值,那么究竟是调(1)好呢,还是调用(2)好呢。于是,我们的重载体系,乃至整个的语法体系都会崩溃。

  这里的核心是表达式的类型。目前,表达式C()的类型是类C。但如果C::C()有返回类型R,那么表达式C()的类型应当是R,而不是C,于是便会引发上述的类型问题。

  2、显式调用构造函数和析构函数

#include <iostream>
using namespace std;
class MyClass
{
  public:   
  MyClass()   
  {       
       cout << "Constructors" << endl;   
  }   
 
  ~MyClass()   
  {
       cout << "Destructors" << endl;
  }
};

int main()
{
   MyClass* pMyClass =  new MyClass;
   pMyClass->~MyClass();
   delete pMyClass;
   return 0;
}

  结果:

  Constructors
  Destructors        //这个是显示调用的析构函数
  Destructors        //这个是delete调用的析构函数

  这有什么用?有时候,在对象的生命周期结束前,想先结束这个对象的时候就会派上用场了。

  由此想到的:

  new的时候,其实做了两件事,一是:调用malloc分配所需内存,二是:调用构造函数。

  delete的时候,也是做了两件事,一是:调用析造函数,二是:调用free释放内存。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号