构造函数与析构函数

1170阅读 0评论2013-10-11 joepayne
分类:C/C++

C++中的对象组合
C++中的类可以使用其它类定义的成员变量,那么如何给对象成员进行初始化呢?
如一下组合示例:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. class M
  4. {
  5. private:
  6.     int mI;
  7. public:
  8.     M(int i)
  9.     {
  10.         printf(" M(int i), i = %d\n",i);
  11.         mI = i;
  12.     }
  13.     int getmI()
  14.     {
  15.         return mI;
  16.     }
  17. };
  18. class Test
  19. {
  20. private:
  21.     const int c;
  22.     M m1;
  23.     M m2;
  24. public:
  25.     Test()
  26.     {
  27.         printf("Test()\n");
  28.     }
  29. };
  30. int main()
  31. {
  32.     Test t1;
  33.     Test t2 = Test();
  34.     printf("Press any key to continue...");
  35.     getchar();
  36.     return 0;
  37. }


上面代码示例不能编译通过,是因为在Test类中的成员变量中有M类对象没有初始化。为此我们可以使用初始化列表对成员变量进行初始化,其语法规则为:
Constructor::Contructor():m1(v1), m2(v2),m3(v3)
{
    //some other assignment operation
}
注意:成员变量初始化顺序与声明的顺序相关,与在初始化列表中的顺序无关;初始化列表先于构造函数的函数体执行的。
小插曲
类中的const成员是肯定会被分配空间的;类中的congst成员变量只是一个只读变量;编译器无法直接得到const成员变量的初始化值,一次无法进入符号表称为真正意义上的常量。
初始化与赋值不同
初始化是用已存在的对象或值对正在创建的对象进行初值设置;
赋值是用已存在的对象或值对已经存在的对象进行值设置;
区别:
初始化:被初始化的对象正在创建
赋值:被赋值的对象已存在。
析构函数-----对象的销毁
如何清理被销毁的对象?
一般而言所有被销毁的对象都需要做清理
解决方案
为每个类都提供一个public的destroy函数,对象不再被需要时立即调用destroy函数进行清理。
但是destroy函数只是一个普通的函数必须显示的调用,如果对象销毁前没有做清理,那么很可能造成资源泄露,在构造函数中申请的资源,需要在对象销毁前释放,这样C++编译器能够自动调用某个特殊函数进行对象的清理。
它就是析构函数。
C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的函数叫做析构函数。
定义:~ClassName()
析构函数没有参数也没有任何返回类型的声明,析构函数在对象销毁时自动被调用。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. class Test
  4. {
  5. public:
  6.     Test()
  7.     {
  8.         printf("Test()\n");
  9.     }
  10.     ~Test()
  11.     {
  12.         printf("~Test()\n");
  13.     }
  14. };
  15. void func()
  16. {
  17.         Test t1;
  18.         Test t2;
  19. }
  20. int main()
  21. {
  22.     func();
  23.     printf("Press any key to continue...");
  24.     getchar();
  25.     return 0;
  26. }


构造函数与析构函数的调用秩序
当类中的成员变量是其它类的对象时,首先调用成员变量的构造函数,调用顺序与声明顺序相同,之后调用自身的构造函数;析构函数的调用秩序与对应的构造函数调用秩序相反。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. class Test
  4. {
  5. private:
  6.     int mI;
  7. public:
  8.     Test()
  9.     {
  10.         printf("Test()\n");
  11.     mI = -1;
  12.     }
  13.     Test(int i)
  14.     {
  15.         printf("Test(int i), i = %d\n", i);
  16.         mI = i;
  17.     }
  18.     Test(const Test& obj)
  19.     {
  20.         printf("Test(const Test& obj),i = %d\n",obj.mI);
  21.         mI = obj.mI;
  22.     }
  23.     ~Test()
  24.     {
  25.         printf("~Test(), i = %d\n", mI);
  26.     }
  27. };
  28. void func(Test t)
  29. {
  30.     Test r(1);
  31. }
  32.     void run()
  33. {
  34.     Test t;
  35.     func(t) ;
  36. }

  37. int main()
  38. {
  39.     run();
  40.     printf("Press any key to continue...");
  41.     getchar();
  42.     return 0;
  43. }


小结:
析构函数是C++中对象销毁时做清理工作的特殊函数,析构函数在对象销毁时自动被调用;析构函数是对象所使用的资源及时释放的保障;析构函数的调用秩序与构造函数相反。
上一篇:B-树与mysql索引
下一篇:C 语言宏用法备忘