zoukankan      html  css  js  c++  java
  • 用汇编的眼光看C++(之const属性) 四


    【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


        const是C/C++语言中的关键字,但是如果用的好,可以极大地提高代码的健壮性。一般来说const使用的地方还是蛮多的,但是主要还是下面几个地方:(1)普通变量的保护;(2)地址空间的保护;(3)类初始变量的声明和保护;(4)类变量在函数中的保护。const的保护主要来自于编译器层面,和程序的运行没有关系。

        (1)普通变量的保护

    1. const int data = 10;  
    2. const char str = 'a';  
    3. const double pi = 3.14;  
        上面的代码就是一组全局变量的定义,如果在函数中变量发生了修改,那么代码就会编译失败。


        (2)地址空间的保护

    1. void process()  
    2. {  
    3.     int value = 10;  
    4.     const int* address = &value;  
    5. }  
        和上面代码不一样的地方就是,这里如果address地址指向的数值发生了改变,那么那么代码就会编译失败?大家可以在函数结束前添加*address = 100;试试看?


        (3)类const成员变量的定义

    1. class desk  
    2. {  
    3.     const int price;  
    4. public:  
    5.     desk():price(10){}  
    6.     ~desk() {}  
    7. };  
        const成员变量 就是在类变量定义的时候前面添加const关键字。和普通的成员变量不一样,const变量在构造函数中一定要初始化操作的。如果没有const关键字,那么在构造函数内部就无所谓是不是需要初始化了。


         (4)类const函数

    1. class desk  
    2. {  
    3.     int price;  
    4. public:  
    5.     desk() {}  
    6.     ~desk() {}  
    7.     void print() {return;}  
    8.     void print() const {return;}  
    9. };  
        那么desk里面的print和print() const函数是不是一样的呢?大家可以看一下这个代码:

    1. 53:       desk m;  
    2. 0040122D   lea         ecx,[ebp-10h]  
    3. 00401230   call        @ILT+75(desk::desk) (00401050)  
    4. 00401235   mov         dword ptr [ebp-4],0  
    5. 54:       m.print();  
    6. 0040123C   lea         ecx,[ebp-10h]  
    7. 0040123F   call        @ILT+70(desk::print) (0040104b)  
    8. 55:       const desk n;  
    9. 00401244   lea         ecx,[ebp-14h]  
    10. 00401247   call        @ILT+75(desk::desk) (00401050)  
    11. 0040124C   mov         byte ptr [ebp-4],1  
    12. 56:       n.print();  
    13. 00401250   lea         ecx,[ebp-14h]  
    14. 00401253   call        @ILT+65(desk::print) (00401046)  
    15. 57:   }  
        上面是一段函数调用的代码。我们在53行和55行定义了desk类型的变量m和n。接着在54行和56行,我们分别利用两个变量调用print函数进行处理,我们发现两个调用的函数地址并不一样,其中一个是0x0040104b,另外一个是0x00401046,我们可以继续跟进去看一下:

    1. 00401046   jmp         desk::print (00401310)  
    2. 0040104B   jmp         desk::print (004012e0)  
        这里虽然是两个跳转函数,但是事实已经证明这里的两个函数确实是不一样的,这也证明了我们的判断是正确的。

  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/sier/p/5676483.html
Copyright © 2011-2022 走看看