c++陷阱之临时变量

来源:互联网 发布:js引用js文件 编辑:程序博客网 时间:2024/04/28 09:58
1.向上强制类型转化产生临时变量
  1. #include <stdio.h>
  2. class Base
  3. {
  4. public:
  5.     int m_b;
  6.     Base(){m_b = 1;}
  7.     void Say(){
  8.       m_b=7;
  9.     };
  10. };
  11. class Drived:public Base
  12. {
  13.     int m_d;
  14. };    
  15. int main()
  16. {
  17.     Derived d;
  18.     ((Base)d).Say();
  19.     printf("%d", d.m_b);
  20.     return 0;
  21. }


我们开始都会认为在调用Say()之后,对象d的m_b成员变量会被修改为7但是结果却输出“1”,原因如下:

这段代码是将对象d的内容拷贝到临时变量中,并且只拷贝Base中有的部分,这样做
就是所谓的“Slicing”。有些书中说这一步是由拷贝构造函数完成的。概念上是这样的,
但是实际上,编译器并没有生成一个真正意义上的拷贝构造函数。

这更进一步说明C++产生了一个临时对象作为强制转换的中间结果。然后以这个临时
对象代替我们的对象d,来调用函数Say()。那么结果自然是,临时变量的m_b被改变,
而我们的d.m_b没有发生变化
这种强制类型转换就是所谓的"向上转型",upcasting。 也叫Object Slicing。这种操作应该小心使用,甚至避免

2.临时变量被存储在寄存器中

  1. void f1( int * &j) 
  2.     int l=20; 
  3.     j=&l; 
  4. void any_function_use_local_variables() 
  5.     int a,b; 
  6.     a=b=1000; 
  7. int main() 
  8.     int *j; 
  9.     f1(j); 
  10.     cout <<*j <<" "
  11.     any_function_use_local_variables(); 
  12.     cout <<*j <<" "
  13.     cout <<*j <<" "
  14.     *j = 10;
  15.     cout << *j;
  16.     return 0; 

上面的例子输出的结果为: 20 1000 4383304

我是这样理解的,如有不妥,还请各位高人指点。

 

int *&j可以这么理解
typedef int * PINT;

void f1(PINT & j)
{
  int l=20;
  j=&l;
}
所以这是一个PINT类型的引用,也就是int * 类型的引用。
因为是引用,所以最后j指向了零时变量l的地址。

零时变量,尤其是整型,编译其一般都把它放在寄存器里。

所以随着寄存器中值的变化,输出的值会不同。

原创粉丝点击