注册 登录
编程论坛 C++教室

关于常引用遇到的问题求解

liudongxing 发布于 2015-08-20 22:14, 436 次点击
试验引用的用法,遇到一个问题,想不通:m和n既然地址都一样,为何输出的值不同?


#include<iostream>
using namespace std;


int main(void)
{
    const int m=200;
    int& n = const_cast<int&>(m);
    n = 300;
    cout << n << endl;
    cout << m << endl;
    cout << &m << endl;
    cout << &n << endl;
      /**********************************
        输出结果为:
        100
        300
        200
        0026FE7C
        0026FE7C
        请按任意继续
        *********************************/

    return 0;
}
2 回复
#2
wmf20142015-08-20 23:23
这就是编译器对常数的处理。经单步发现,当显示m时,并不是在m位置处取数,而是直接将常数0xC8(200)压入栈供cout显示,下述编译后的汇编代码可以很清楚看到:
10:       cout << n << endl;
004017BE   push        offset @ILT+200(std::endl) (004010cd)
004017C3   mov         edx,dword ptr [ebp-8] //ebp-8是变量n的地址,这时n的内容为m的地址,可以看到n实际上已成为一个指针变量,此句把m的地址送到寄存器EDX中
004017C6   mov         eax,dword ptr [edx]   //寄存器间址寻址方式把EDX指向的地址(变量m)处的值(300、0x12c)送到EAX中
004017C8   push        eax                   //数据300入栈供cout显示
004017C9   mov         ecx,offset std::cout (00477a10)
004017CE   call        @ILT+255(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401104)
004017D3   mov         ecx,eax
004017D5   call        @ILT+480(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e5)
11:       cout << m << endl;
004017DA   push        offset @ILT+200(std::endl) (004010cd)
004017DF   push        0C8h   //直接把数据200(0xc8)入栈供cout显示,可以看到显示m的值,编译器好像#define m 80一样宏定义替代了
004017E4   mov         ecx,offset std::cout (00477a10)
004017E9   call        @ILT+255(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401104)
004017EE   mov         ecx,eax
004017F0   call        @ILT+480(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e5)
#3
rjsp2015-08-21 09:28
问题就在这一句
int& n = const_cast<int&>(m);
n = 300;
你修改了一个常量,未定义行为。
1