Re: [問題] 如何讓vector<A> Get()得到的資料不可修改

看板C_and_CPP作者 (小乖)時間14年前 (2009/12/16 13:03), 編輯推噓0(0010)
留言10則, 3人參與, 最新討論串3/3 (看更多)
這個程式我拿到 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

12/16 16:45, , 1F
2,3步驟可由NRVO優化成為一步,直接構建vector<A> tmp。
12/16 16:45, 1F

12/16 20:58, , 2F
昨天問題沒打好, 但是就像s大講重新敘述的一樣
12/16 20:58, 2F

12/16 20:58, , 3F
這次真的是對vector的copy ctor有深深的認識了,
12/16 20:58, 3F

12/16 20:58, , 4F
s大居然連m_Info 有 pointer 指向相同物件都想到了XD
12/16 20:58, 4F

12/16 21:11, , 5F
但是使用vector <const A> tmp, 要怎麼給tmp初始阿
12/16 21:11, 5F

12/16 21:13, , 6F
Constructor cannot be declared 'const'
12/16 21:13, 6F

12/16 21:21, , 7F
還是試不出來XDD compiler還是告訴我上面那句話
12/16 21:21, 7F

12/16 22:46, , 8F
vector<const A> tmp = test.GetInfo();
12/16 22:46, 8F

12/16 22:46, , 9F
tmp.push_back( A() );
12/16 22:46, 9F

12/16 23:41, , 10F
無法從 'std::vector'轉換為 'const std::vector'
12/16 23:41, 10F
文章代碼(AID): #1BA6eDHC (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1BA6eDHC (C_and_CPP)