经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C » 查看文章
C++基础 对象的管理——单个对象的管理
来源:cnblogs  作者:还想抢救抢救  时间:2018/10/16 9:36:10  对本文有异议

1. 为什么要有构造函数和析构函数

  面向对象的思想是从生活中来,手机、车出厂时,是一样的。

  这些对象都是被初始化后才上市的,初始化是对象普遍存在的一个状态。

  普通方案:

    对每个类提供一个 init 函数,对象创建后立即调用 init 函数进行初始化。

    这种方案麻烦,并且不易用于对象数组。

  所以需要构造函数,对应需要析构函数。

2. 对象的构造

  (1)构造函数的定义

    C++类可以定义与类名相同的特殊成员函数,此函数为构造函数。

    构造函数在定时可以有参数,但无任何返回类型声明。

  (2)构造函数的调用

    自动调用:对象定义时,C++编译器会自动调用构造函数。

    手动调用:程序员可手动调用。

  (3)构造函数的分类

  

  1. //有参数构造函数的三种调用方法
  2. class Test
  3. {
  4. private:
  5. int a;
  6. int b;
  7. public:
  8. //无参数构造函数
  9. Test()
  10. {
  11. ;
  12. }
  13. //带参数的构造函数
  14. Test(int a, int b)
  15. {
  16. ;
  17. }
  18. //赋值构造函数
  19. Test(const Test &obj)
  20. {
  21. ;
  22. }
  23. public:
  24. void init(int _a, int _b)
  25. {
  26. a = _a;
  27. b = _b;
  28. }
  29. };

  (4)构造函数的调用

    (a)无参构造函数

  1. Test t1,t2;

    (b)有参构造函数

  1. //有参数构造函数的三种调用方法
  2. class Test5
  3. {
  4. private:
  5. int a;
  6. public:
  7. //带参数的构造函数
  8. Test5(int a)
  9. {
  10. printf("\na:%d", a);
  11. }
  12. Test5(int a, int b)
  13. {
  14. printf("\na:%d b:%d", a, b);
  15. }
  16. public:
  17. };
  18. int main55()
  19. {
  20. Test5 t1(10); //c++编译器默认调用有参构造函数 括号法
  21. Test5 t2 = (20, 10); //c++编译器默认调用有参构造函数 等号法
  22. Test5 t3 = Test5(30); //程序员手工调用构造函数 产生了一个对象 直接调用构造构造函数法
  23. system("pause");
  24. return 0;
  25. }

    (c)拷贝构造

【1】在函数体内的拷贝构造

注意与拷贝函数区分。

  1. #include "iostream"
  2. using namespace std;
  3. class AA
  4. {
  5. public:
  6. AA() //无参构造函数 默认构造函数
  7. {
  8. cout<<"我是无参构造函数,自动被调用了"<<endl;
  9. }
  10. AA(int _a) //无参构造函数 默认构造函数
  11. {
  12. a = _a;
  13. cout << "我是有参构造函数" << endl;
  14. }
  15. AA(const AA &obj2)
  16. {
  17. cout<<"我也是拷贝构造函数,我是通过另外一个对象obj2,来初始化我自己"<<endl;
  18. a = obj2.a + 10;
  19. }
  20. ~AA()
  21. {
  22. cout<<"我是析构函数,自动被调用了"<<endl;
  23. }
  24. void getA()
  25. {
  26. printf("a:%d \n", a);
  27. }
  28. protected:
  29. private:
  30. int a;
  31. };
  32. //单独搭建一个舞台
  33. void ObjPlay01()
  34. {
  35. AA a1; //变量定义
  36. //赋值构造函数的第一个应用场景
  37. //用对象1 初始化 对象2
  38. AA a2 = a1; //定义变量并初始化 //初始化法
  39. a2 = a1; //用a1来=号给a2 编译器给我们提供的浅copy
  40. }
  41. int main()
  42. {
  43. ObjPlay01();
  44. system("pause");
  45. }

【2】函数传参时的拷贝构造

  1. #include "iostream"
  2. using namespace std;
  3. class Location
  4. {
  5. public:
  6. Location( int xx = 0 , int yy = 0 )
  7. {
  8. X = xx ; Y = yy ; cout << "有参构造\n" ;
  9. }
  10. Location( const Location & p ) //复制构造函数
  11. {
  12. X = p.X ; Y = p.Y ; cout << "拷贝构造" << endl ;
  13. }
  14. ~Location()
  15. {
  16. cout << X << "," << Y << " 析构" << endl ;
  17. }
  18. int GetX () { return X ; } int GetY () { return Y ; }
  19. private : int X , Y ;
  20. } ;
  21. //alt + f8 排版
  22. void f ( Location p )
  23. {
  24. cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ;
  25. }
  26. void mainobjplay()
  27. {
  28. Location A ( 1, 2 ) ; //形参是一个元素,函数调用,会执行实参变量初始化形参变量
  29. f ( A ) ;
  30. }
  31. void main()
  32. {
  33. mainobjplay();
  34. system("pause");
  35. }

【3】函数返回与拷贝构造

注意匿名对象的拷贝构造,和析构。

  1. //第四个应用场景
  2. #include "iostream"
  3. using namespace std;
  4. class Location
  5. {
  6. public:
  7. Location( int xx = 0 , int yy = 0 )
  8. {
  9. X = xx ; Y = yy ; cout << "构造函数\n" ;
  10. }
  11. Location( const Location & p ) //复制构造函数
  12. {
  13. X = p.X ; Y = p.Y ; cout << "拷贝构造" << endl ;
  14. }
  15. ~Location()
  16. {
  17. cout << X << "," << Y << " 析构函数" << endl ;
  18. }
  19. int GetX () { return X ; } int GetY () { return Y ; }
  20. private : int X , Y ;
  21. } ;
  22. //alt + f8 排版
  23. void f ( Location p )
  24. {
  25. cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ;
  26. }
  27. Location g()
  28. {
  29. Location A(1, 2);
  30. return A;
  31. }
  32. //对象初始化操作 和 =等号操作 是两个不同的概念
  33. //匿名对象的去和留,关键看,返回时如何接
  34. void mainobjplay()
  35. {
  36. //若返回的匿名对象,赋值给另外一个同类型的对象,那么匿名对象会被析构
  37. Location B;
  38. B = g(); //用匿名对象 赋值 给B对象,然后匿名对象析构
  39. //若返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象
  40. //Location B = g();
  41. }
  42. void main()
  43. {
  44. mainobjplay();
  45. system("pause");
  46. }

第二种情况:

定义一个新符号去接匿名对象,那么匿名对象会直接转换成新符号对象。

  1. //第四个应用场景
  2. #include "iostream"
  3. using namespace std;
  4. class Location
  5. {
  6. public:
  7. Location( int xx = 0 , int yy = 0 )
  8. {
  9. X = xx ; Y = yy ; cout << "构造函数\n" ;
  10. }
  11. Location( const Location & p ) //复制构造函数
  12. {
  13. X = p.X ; Y = p.Y ; cout << "拷贝构造" << endl ;
  14. }
  15. ~Location()
  16. {
  17. cout << X << "," << Y << " 析构函数" << endl ;
  18. }
  19. int GetX () { return X ; } int GetY () { return Y ; }
  20. private : int X , Y ;
  21. } ;
  22. //alt + f8 排版
  23. void f ( Location p )
  24. {
  25. cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ;
  26. }
  27. Location g()
  28. {
  29. Location A(1, 2);
  30. return A;
  31. }
  32. //对象初始化操作 和 =等号操作 是两个不同的概念
  33. //匿名对象的去和留,关键看,返回时如何接
  34. void mainobjplay()
  35. {
  36. //若返回的匿名对象,赋值给另外一个同类型的对象,那么匿名对象会被析构
  37. // Location B;
  38. //B = g(); //用匿名对象 赋值 给B对象,然后匿名对象析构
  39. //若返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象
  40. Location B = g();
  41. }
  42. void main()
  43. {
  44. mainobjplay();
  45. system("pause");
  46. }

  (5)默认构造函数

  两个特殊的构造函数:

  1)默认无参构造函数

    当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空。

  2)默认拷贝构造函数

    当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,进行浅拷贝。

  (6)构造函数调用规则

  1)当类中没有定义任何一个构造函数时,c++编译器提供默认无参构造函数和默认拷贝构造函数。

  2)当类中定义了拷贝构造函数时,c++编译器不会提供拷贝构造函数。

  3)当类中定义了任意非拷贝构造函数,c++编译器不会提供默认无参构造函数。

 

 

3. 对象的析构

  (1)析构函数的定义

    语法:~className()

    作用:清理对象

  (2)析构函数的调用

    对象析构时,C++编译器自动调用。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号