一個十多行的C++程序求教,關於引用數據成員的問題。


#include <iostream>
#include <string>
using namespace std;
class A
{
public:
A(string ts):s(ts){}
string& getS(){return s;}//
private:
string& s;
};
int main()
{
A a("dd");
cout<<a.getS()<<endl;
return 0;
}
為啥輸出亂碼?
getS()如果返回string,而不是string&運行時錯誤。
求哪位大牛解釋一下。。。

18 个解决方案

#1



#include  <iostream> 
#include  <string> 
using namespace std; 
class A 

public: 
    A(string ts):s(ts){} 
    string& getS(){return s;}// 
private: 
    string s; 
}; 
int main() 

    A a("dd"); 
    cout <<a.getS() <<endl; 
    return 0; 

#2


你的引用引用到了一個局部變量上面了。
他引用到s(ts中的ts
而ts是局部變量。用完就釋放了。
所以把類成員改為非引用

#3


string s ="dd";
A a(s);
cout<<a.getS()<<endl;
可是這樣也不行,前提是我用vc跑的。
如果用devc++就行了。

#4


3樓的方法也不對。
A a(s); 也要復制一個s的拷貝,也是個臨時對象

把構造函數改成:
A(string& ts)


vc6.0可以

#5


扔了vc6.0

#6


麻煩推薦個符合標准的c++集成環境,多謝多謝,一直在用vc6,雖然知道他很多地方不合標准:(

#7


gcc

#8


visual C++ 2008 express

#9


類的構造函數是得到ts的引用,而ts是個局部變量...當然亂了...
string s 這樣就好了

#10


至少在這個問題上,不是vc6.0的錯。對於3樓的情況,devc++只是“恰好”沒有把問題表現出來,而不是這種方法本身正確。

請按照1樓或4樓的方法修改。

#11


我的理解是devc++和vc6在作用域的定義上不同吧,
vc6:
    A a("dd");  // "dd"在進入構造函數后才分配,出了函數體則收回
devc++:
    A a("dd");  // "dd"在進入構造函數前就分配了,所以除了函數體它仍然存在

到底哪個符合C++ standard,哪位查一下吧
我決得vc6的做法更好,“盡量晚的分配內存,盡早的收回內存”

#12


以下引自《C++ Standard -- ISO/IEC 14882:2003》

The potential scope of a function parameter name in a function definition (8.4) begins at its point of declaration. // from [basic.scope.local]
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument....The lifetime of a parameter ends when the function in which it is defined returns. The initialization and destruction of each parameter occurs within the context of the calling function. // from [expr.call]

所以函數的形參應該在調用處的上下文中(而非函數內部,請注意the context of the calling function,而非the context of the called function)構造和析構。由於形參的作用域為函數體,因此編譯器可以在調用函數之前構造,在返回后立即析構(不過標准並沒有強制要求這一點,函數返回后即使不立即析構也是可以的)。
實驗了一下devc++,它也是在函數返回后立即析構形參的,這一點和vc6.0相同。

我覺得devc++之所以在3樓的代碼中運行正常,是因為其string的實現,我估計它采取了引用計數。這樣就能解釋樓主的原始代碼不行,而3樓的代碼可以了。總之它是由devc++的特定實現造成的,並非3樓的代碼本身正確。

#13


恩,有一點說錯了,由於
The lifetime of a parameter ends when the function in which it is defined returns. 
並且
The lifetime of an object of type T ends when:
— if T is a class type with a non-trivial destructor (12.4), the destructor call starts... // from [basic.life]
所以形參的析構函數必須在函數返回后立即調用。這一點devc++和vc6.0都是符合的。

#14


樓上居然看了c++標准原版。太長了,我找不到想看的內容。

#15


專注c++\c技術
qq群 35011905
be yourself best

#16


using namespace std;
class A 

public: 
A(string& ts):s(ts){}
string& getS(){return s;}//
private:
string& s;
};

int main(int argc, char* argv[])
{
string t="dd";
A a(t);
cout <<a.getS() <<endl;
getch();
return 0;
}

#17


在BCB2007中,樓主的原代碼報錯:
[BCC32 Error] Quote1.cpp(13): E2359 Reference member 'A::s' initialized with a non-reference parameter
我根據錯誤介紹進行了上面的修改,可以通過
就是有些麻煩,呵呵
還是Chiyer回復的簡練,學習ing

#18


謝謝各位啦,算是知道啦!

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com