关于临时变量

什么是临时对象?

        C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象.

通常出现在以下两种情况:

(1)为了使函数调用成功而进行隐式类型转换的时候

       传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁。如下例:

  //计算字符ch在字符串str中出现的次数

   int countChar (const string& str, char ch);  

  char buffer[]; 

  char c; 

  //调用上面的函数 

  countChar (buffer, c);

    

我们看的第一个参数为char[],而函数的参数类型为const string&,参数不一致,看看能否进行隐式转化,string类有个构造函数是可以作为隐式转化函数(参见5)的。那么编译器会产生一个 string的临时变量,以buffer为参数进行构造,那么countChar中的str参数会绑定到此临时变量上,直到函数返回时销毁。

注意这样的转化只会出现在两种情况下:函数参数以传值(by value)的方式传递 或者 对象被传递到一个 reference-to-const 参数上。

(1)传值方式

int countChar (string str, char ch); 

string buffer; 

char c; 

//参数通过传值方式传递 

countChar (buffer, c);


这种方法会调用string的拷贝构造函数生成一个临时变量,再将这个临时变量绑定到str上,函数返回时进行销毁。

传常量引用:

开始的实例即是属于这种情况,但一定强调的是传递的是const型引用,如将开始函数的原型改为:

   int countChar (string& str, char ch);


下面调用相同,编译器会报错!为什么C++设计时要求 当对象传递给一个reference-to-non-const 参数不会发生隐式类型转化呢?

下面的实例可能向你说明这样设计的目的:

//声明一个将str中字符全部转化为大写 

 void toUpper (string& str);  

 char buffer[] = "hazirguo"; 

 toUpper(buffer);      //error!!非const引用传递参数不能完成隐式转化 

如果编译器允许上面的传递完成,那么,会生成一个临时对象,toUpper函数将临时变量的字符转化为大写,返回时销毁对象,但是对buffer内容毫无影响!程序设计的目地是期望对“非临时对象”进行修改,而如果对reference-to-non-cosnt对象进行转化,函数只会对临时变量进行修改。这就是为什么C++中要禁止non-const-reference参数产生临时变量的原因了。

 

(2)当函数返回对象的时候。

        当函数返回一个对象时,编译器会生成一个临时对象返回,如声明一个函数用来合并两个字符串:

   const string strMerge (const string s1, const string s2);


函数声明:const char *c_str();

  c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.

  这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。

  注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针

  比如:最好不要这样:

   char* c; 

  string s="1234"; 

  c = s.c_str(); 

c最后指向的内容是垃圾,因为s对象被析构,其内容被处理(纠正:s对象的析构是在对指针c完成赋值操作之后进行的,故此处并没有错误)

应该这样用:

  char c[20]; 

 string s="1234"; 

 strcpy(c,s.c_str());

这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作

  ———再举个例子———

  c_str() 以const char* 类型返回 string 内含的字符串

  如果一个函数要求char*参数,可以使用c_str()方法:

       string s = "Hello World!"; 
      printf("%s", s.c_str()); //输出 "Hello World!" 


c_str在打开文件时的用处:

  当需要打开一个由用户自己输入文件名的文件时,可以这样写:ifstream in(st.c_str());。其中st是string类型,存放的即为用户输入的文件名。

 

总结:

             当我们看到一个reference-to-const参数时,极可能一个临时对象绑定到该参数上;

             当我们看到函数返回一个对象时,就会产生临时对象。



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值