2012-03-08 46 views
2

我不得不承認我的C++有點生疏。在一個項目中,我嘗試創建一個類的向量並使用它們。有一個問題,因爲我想用一個唯一的指針來識別矢量的每個條目以便快速訪問,但它不起作用。這裏是我的問題的一個小例子:C++自引用類

#include <iostream> 
#include <vector> 

class Foo{ 
public: 
Foo() { ptr = this; } 
~Foo() {} 
Foo * ptr; 
}; 

int main() 
{ 
std::vector<Foo> vec; 
for(unsigned int i = 0; i < 2; ++i) 
    vec.push_back(Foo()); 
for(unsigned int i = 0; i < vec.size(); ++i) 
std::cout << "Object Self-Pointer: " << std::hex << reinterpret_cast<unsigned int>(vec[i].ptr) << std::endl; 
} 

實際輸出:

Object Self-Pointer: bfbebc18 
Object Self-Pointer: bfbebc18 

預期輸出:

Object Self-Pointer: bfbebc18 
Object Self-Pointer: bfbebc1c 

(一些指針到實際的對象)。

我希望你能幫助我解決這個問題,謝謝你提前。

+4

請注意,這是更簡單用'的&'不是維護總是包含一個成員變量獲取對象的地址值。所以你會說'&vec [5]'而不是'vec [5] .ptr',並且不需要打印複製構造函數和賦值操作符。 – sth 2012-03-08 21:14:51

+0

@sth謝謝你提到,但我需要確保始終使用相同的指針,因爲我在不同的地方使用它來識別類。只是使用「&」不能保證我使用了相同的指針(是嗎?):) – Listing 2012-03-08 21:17:49

+0

你真正想要的是一張地圖 – 2012-03-08 21:22:19

回答

10

當你這樣做:

vec.push_back(Foo()); 

一個新的臨時Foo對象被創建,但每次在同一地址創建時間(因爲它是在堆棧和堆棧指針創建是一樣的)。所以this指針,因此這些實例中每個的ptr成員是相同的。

當你每個實例添加到載體,默認拷貝構造函數被調用,所以ptr成員被複制,因此在矢量所有實例都具有相同的價值。

+0

* facepalm *當然!謝謝:-) – Listing 2012-03-08 21:10:49

1

當您撥打push_back(Foo())時,會構造一個對象,然後vector將獲取該對象的副本。由於Foo正在使用默認的拷貝構造函數,它將存儲由Foo()創建的臨時對象的this指針。臨時對象的地址在循環的兩次迭代中似乎都是相同的。

3

std :: vector存儲對象的副本(這是對象類型是可複製構造的要求)。在這種情況下,Foo的複製構造函數由編譯器自動生成。

所以,當你這樣做的push_back(富()),你正在做的:

1) Create a Foo() object. Set ptr to bfbebc18 
2) Copy it, and put it into vector<Foo> 
3) Delete the original Foo from which it came 
4) Create a new Foo() object. Set ptr to bfbebc18 (the same location is used because it's temporary) 
5) Copy it and put it into vector<Foo> 
+0

如果使用'vector ',並使用vec.push_back(new Foo()),問題會解決嗎? – Topo 2012-03-08 21:18:23

+0

@Topo也許但我不想摧毀我自己的物體。 – Listing 2012-03-08 21:19:34

+0

boost有一個指針矢量solvd爲你 – 2012-03-08 21:23:49

1

正如其他人所提到的,問題是,push_back推動對象的副本到堆棧,這是使用複製構造函數創建的,該構造函數執行成員變量的成員副本。

解決這個問題的一種方法是定義一個拷貝構造函數來做你想要的;例如:

Foo(const Foo& rhs) { ptr = this;} 

與此運行,我得到的輸出:

Object Self-Pointer: 4b0308 
Object Self-Pointer: 4b030c 
+0

雖然正確,你正在幫助繼續他的錯誤路徑 – 2012-03-08 21:24:33