狄泰C++课程学习笔记:第二十四课:经典问题解析二

本次主要举例解析3个问题:

    * 析构函数的调用顺序

    * 定义const对象(只读对象)时,我们需要注意一些什么

    * this指针的引入

1、析构函数的调用顺序

    提及析构函数的调用顺序,我们需要首先来回顾一下构造函数的调用顺序

    单个对象的构造顺序为:

        * 先调用父类的构造函数

        * 在调用类中的成员对象的构造函数(这里的成员对象需要在初始化列表中进行初始化的工作,且初始化顺序只与对象成员的声明顺序相同)

        * 调用自己的构造函数

    那么,析构函数的调用顺序就是:和构造函数的调用顺序刚好相反

实例代码如下:

  1 #include <stdio.h>
  2
  3 class Member
  4 {
  5     int _mi;
  6 public:
  7     Member(int v)
  8     {
  9         _mi = v;
 10         printf("Member: v = %d\n", v);
 11     }
 12     ~Member()
 13     {
 14         printf("~Member(): _mi = %d\n", _mi);
 15     }
 16 };
 17
 18 class Test
 19 {
 20     Member _mB;
 21     Member _mA;
 22 public:
 23     Test() : _mA(0), _mB(1)
 24     {
 25         printf("Test()\n");
 26     }
 27     ~Test()
 28     {
 29         printf("~Test()\n");
 30     }
 31 };
 32
 33 Member mC(5);
 34
 35 int main(int argc, char** argv)
 36 {
 37     Test t;
 38
 39     return 0;
 40 }

2、定义const对象(只读对象)时,我们需要注意一些什么

* 单个对象在定义时使用const来修饰,则该对象成为只读对象,区分于真正意义上的常量

* const对象只能调用类中的const修饰的成员函数,且该在函数中不能修改成员变量的值

* 一个类中,我们自己手工定义了拷贝构造函数,则形参obj就是一个const对象,拷贝构造函数中对该对象的使用仍然遵从const对象的使用规则

示例内容如下:

  1 #include <stdio.h>
  2
  3 class Test
  4 {
  5     int _mi;
  6 public:
  7     Test(int v)
  8     {
  9         _mi = v;
 10     }
 11     Test(const Test& obj)
 12     {
 13         _mi = obj._mi;
 14         // _mi = obj.getMI();
 15         printf("Test(const Test& obj)\n");
 16     }
 17     void setMI(int v)
 18     {
 19         _mi = v;
 20     }
 21     int getMI()
 22     {
 23         return _mi;
 24     }
 25 };
 26
 27 int main(int argc, char** argv)
 28 {
 29     Test t(0);
 30
 31     printf("t.mi = %d\n", t.getMI());
 32
 33     // t.setMI(5);
 34
 35     // printf("t.mi = %d\n", t.getMI());
 36
 37     Test tt(t);
 38     return 0;
 39 }

3、this指针的引入

每个定义出来的实体对象,在内存中都会有其唯一对应的内存地址,我们都知道:对于一个已经存在的类的不同对象来说,每个对象都有自己独有的成员变量,但是成员函数却是大家公用一套,那么编译器如何来确定当前到底是哪个对象调用了成员函数,从而去改变哪个对象的成员变量的值呢?

实际上,在我们每次调用类中的非静态成员函数时,编译器都会默认的传递一个名为this的实参进去,该this即代表着当前调用该函数的对象本身,this的值即为该对象在内存中的首地址,这样,编译器就可以使用当前调用的成员函数来改变this当前所指代的对象的成员变量的值了。。。

小例如下:

  1 #include <stdio.h>
  2
  3 class Test
  4 {
  5     int _mi;
  6 public:
  7     Test(int v)
  8     {
  9         _mi = v;
 10     }
 11     int getMI()
 12     {
 13         return _mi;
 14     }
 15     void print()
 16     {
 17         printf("this = %p\n", this);
 18     }
 19 };
 20
 21 int main(int argc, char** argv)
 22 {
 23     Test t1(0);
 24     printf("t1._mi = %d\n", t1.getMI());
 25     printf("&t1 = %p\n", &t1);
 26     t1.print();
 27
 28     Test t2(1);
 29     printf("t2._mi = %d\n", t2.getMI());
 30     printf("&t2 = %p\n", &t2);
 31     t2.print();
 32
 33     return 0;
 34 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值