快穿嫖反派完结微盘:函数返回值

来源:百度文库 编辑:中财网 时间:2024/04/28 01:53:44
你有函数如下: 

string   fun() 

      return   "some ";//这儿调用string的一个转换构造函数构造一个临时对象! 


如上注释,临时对象用以保存fun的返回值,该临时对象的字符串是 "some "。 

接下来在程序中: 

///////情况一: 
const   char*   c   =   fun().c_str(); 

根据C++标准对临时对象生命期的规定一,上述临时对象必须在 "fun().cstr() "执行(表达式求值)完毕后,才可被摧毁!,所以类似C++伪码是: 

string   _strTemp   =   fun();//_strTemp是临时匿名对象! 
const   char*   _cTemp   =   _strTemp.cstr(); 
_strTemp.~string();//临时对象在此析构! 
const   char*   c   =   _cTemp; 

注意,临时对象析构的时候,在它的析构函数中调用了delete[]删除了字符缓存区!所以此时以c指针退化成了一个void*,因此你的情况一是: 

c值的内容不可预见,在此例中是 " ",即:   cout   < <   c;//将输出 " "! 


情况二 
string&   str   =   fun(); 
const   char*   c   =   str.c_str(); 

在此例中fun同样是返回一个临时对象,不同的是这次是以接受返回值的string引用绑定这个临时对象,这样一来,根据C++标准对临时对象生命期的规定二,fun产生的那个临时对象必须要等绑定它的引用str的生命期结束,它才可以被析构! 

这样,只要c与str的生命期同步,c将有效的指向那个临时对象的字符缓存区,所以你的情况之二是: 

c中存 "some ",我大胆的推测,你的程序测试代码应该类似如下: 

int   main() 

      ///////情况一//// 
      const   char*   c   =   fun().c_str(); 
      cout   < <   c   < <   endl;//输出 " "! 

        //////情况二 
        string&   str   =   fun(); 
        c   =   str.c_str(); 
        cout   < <   c   < <   endl;//c与str生命期同步,c因此总是指向有效的字符buffer!   "some " 

        return   0;//str、c以及那个临时对象在此析构! 



你的问题很简单: 

int   ai() 

      return   1; 


.... 

int&   i   =   ai();   //为何编译通不过? 

是因为 '1 '是一个常量型对象,而你以一个非常型引用指向常型的临时对象,显然违反了语言‘不能以非常型引用绑定常量对象 '的规则,故不能通过编译! 

另外,你说: 

string&   str   =   fun(); 
这里string&也不是const引用啊!!!! 

虽然 "some "是常型字符串,但是在被转换成string临时对象的时候,是这个常字符串被复制到了该临时对象的buffer!该buffer不是常量字符数组,该临时对象也不是常型对象,所以, 

string&   str   =   fun(); 
这里string&也不是const引用啊!!!! 

是非常自然的事情,不应有疑问的!