作者spider391 (小乖)
看板C_and_CPP
標題Re: [問題] 如何讓vector<A> Get()得到的資料不可修改
時間Wed Dec 16 13:03:06 2009
這個程式我拿到 VC 2005 去 compile 後
我修改了原 po 的程式如下:
#include <iostream>
#include <vector>
using namespace std;
: class A{
// 拿掉 ... 註解
: };
: class B{
: public:
: B() {};
: const vector<A> GetInfo() {return m_Info;}
: private:
: vector<A> m_Info;
: };
int main() // main 要加上 回傳值型態
: {
B test; // 原本 B test(); <- 此方式會讓 compiler 以為是 function 宣告
vector<A> tmp = test.GetInfo(); // B.GetInfo() 會讓 compiler error XD
: }
我解釋一下 vector<A> tmp = test.GetInfo();
實際上做了什麼事情。
1. 呼叫 test.GetInfo()
2. 回傳時,產生一個 const vector<A> 的 temp 物件 (call copy constructor)
3. 初始化 vector<A> tmp = temp; (call copy constructor)
注意 3,雖然是用 vector<A> tmp = temp; = 的語法,但實際是呼叫
copy constructor 來完成初始話的動作。 ie. vector<A> (const vector<A>& obj);
這裡有趣的是 vector<A> (const vector<A> obj) 會透過 A 的 copy constructor
來完成每個元素的初始化動作。因為 class A 沒有宣告 copy constructor
所以 compiler 會貼心的幫你自動產生。
所以此 statement vector<A> tmp = test.GetInfo(); 就有兩次的 copy constructor
呼叫的動作。
而 copy constructor 是複製一份的觀念,所以基本上
test.m_Info 和 tmp.m_Info 是兩個不同的物件
修改 tmp.m_Info 無關乎 test.m_Info (除非 m_Info 有 pointer 指向相同物件)
原 po 的意思可能是無論如何不要修改到 A
那有兩個方法 (應該有更多方法)
1. 若是不想修改物件 A 本身 那使用 vector <const A>
2. 其他存取 A 的介面 宣告成 const eq. void read_A() const;
3. 原 po 的 const vector<A> tmp 方法 (我覺得這樣宣告很好,語意很清楚)
大概是這樣。
關於 copy constructor 我是參考
"C++ 物件模型 (Inside The C++ Object Model)" (Lippman著 侯捷譯)
裡面對於物件的生成以及物件模型有很詳細的探討 ~~
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.134.96.34
→ dp2:2,3步驟可由NRVO優化成為一步,直接構建vector<A> tmp。 12/16 16:45
→ HeyScng:昨天問題沒打好, 但是就像s大講重新敘述的一樣 12/16 20:58
→ HeyScng:這次真的是對vector的copy ctor有深深的認識了, 12/16 20:58
→ HeyScng:s大居然連m_Info 有 pointer 指向相同物件都想到了XD 12/16 20:58
→ HeyScng:但是使用vector <const A> tmp, 要怎麼給tmp初始阿 12/16 21:11
→ HeyScng:Constructor cannot be declared 'const' 12/16 21:13
→ HeyScng:還是試不出來XDD compiler還是告訴我上面那句話 12/16 21:21
→ spider391:vector<const A> tmp = test.GetInfo(); 12/16 22:46
→ spider391:tmp.push_back( A() ); 12/16 22:46
→ HeyScng:無法從 'std::vector'轉換為 'const std::vector' 12/16 23:41