2015-07-10 34 views
0

我遇到了一個令我感到困惑的問題。這與我是選擇存儲對象還是指向它的指針有關。字符串在構造函數中被賦值,但之後變爲空白C++

這是我的課:

class Test { 
public: 
    std::string abc; 
    int x; 

    Test(std::string def, int y) { 
     abc = def; 
     cout << abc << endl; //THIS ALWAYS GIVES "ghi" 
     x = y; 
    } 
}; 

把它作爲一個指針:

Test* T1 = &Test{ "ghi", 100 }; 
    cout << T1->abc << endl; //**THIS IS BLANK -- WHY!?** 
    cout << T1->x << endl; //THIS GIVES 100 

把它作爲一個對象本身:

Test T2 = Test{ "ghi", 100 }; 
    cout << T2.abc << endl; //THIS GIVES "ghi" 
    cout << T2.x << endl; //THIS GIVES 100 

我是比較新的C++但基於我的理解,T1-> abc應該取消引用指針T1(因此我有一個Test對象),然後訪問m對該Test對象的abc進行ember。由於我已經創建了該對象,因此應該是「ghi」。但是,這是空白的。

顯然,這隻適用於字符串成員,而不是整數成員,因爲T1-> x正常工作。

當我存儲對象而不是指向它的對象時,問題不存在,如對象T2所示。

我檢查過在T1和T2施工期間,abc總是「ghi」裏面的的構造函數。不知何故,建設後,字符串就消失了。

此外,根據我讀到的,abc = def複製字符串內容而不是指針,所以它可能不是範圍問題。

https://msdn.microsoft.com/en-us/library/b930c881.aspx非常清楚,在任何情況下,是否 - >或。被使用,可以進行分配。

搜索谷歌和stackoverflow沒有幫助。因此你的讚賞。提前致謝。

class Test { 
public: 
    std::string abc; 
    int x; 

    Test(std::string def, int y) { 
     abc = def; 
     x = y; 
    } 
}; 

int main() { 

    Test* T1 = &Test{ "ghi", 100 }; 
    cout << T1->abc << endl; //THIS IS BLANK -- WHY!? 
    cout << T1->x << endl; //THIS GIVES 100 

    Test T2 = Test{ "ghi", 100 }; 
    cout << T2.abc << endl; //THIS GIVES "ghi" 
    cout << T2.x << endl; //THIS GIVES 100 

    return 0; 
} 
+5

'Test * T1 =&Test {「ghi」,100};'這是錯誤的。不要這樣做。您將該指針重新設置爲臨時對象的地址(在該行的分號後不會存在)。 – Borgleader

+1

據我所知,g ++甚至不會讓你編寫這樣的代碼。 –

+0

在我的實際問題中,我有一個抽象基類,稱之爲測試。我也有一些派生類,但是我選擇實例化的派生類只能在運行時確定。因此,我正在使用指向Test的指針來保存派生類的指針。因此我需要一個指針。有一個更好的方法嗎? – emoPuppy

回答

2

此構造:

Test{ "ghi", 100 }; 

創建臨時變量,您試圖指向。這是錯誤的。

如果你想存儲它使用指針:

Test* T1 = new Test{ "ghi", 100 }; 

cout << T1->abc << endl; //This is not blank anymore 
cout << T1->x << endl; 

delete T1; //Do NOT forget this! 

順便說一句,如果你想知道,爲什麼這條線:

cout << T1->x << endl; 

仍在評估,以100:當對象被銷燬,其所有成員也被銷燬(在調用它們的析構函數方面)。由於xint,因此它在非操作中的析構函數和其佔用的內存內容不會更改。

另一方面,abc是和std::string,它在銷燬期間釋放分配的內存 - 因此T1->abc指的是空字符串。

+0

謝謝(還有其他的)。對於問什麼竟然是這樣一個直截了當的問題抱有歉意。學習一種新語言當然不容易。我閱讀了一些建議,我們應該避免使用新版本,因爲非新版本在不再需要時會自動刪除。所以我從這裏得出的結論是,只有當對象本身被變量引用時,「自動」纔會考慮它是否被指針引用。 – emoPuppy

1
Test* T1 = &Test{ "ghi", 100 }; 

請不要這樣做。這正是導致你的問題。而是使用

Test* T1 = new Test("ghi", 100); 

因爲第一種方式創建一個臨時對象,你試着去打印字符串之前它消失的參考。

它適用於非指針,因爲您將臨時對象賦予新對象。

不記得刪除(因爲你已經使用了新)

delete T1; 

或者,如πάνταῥεῖ指出的那樣,這將是更安全,更好的C++編碼習慣,將使用smart pointer。想到的最相關的是unique_ptr。

std::unique_ptr<Test> T1(new Test()); 
std::cout << T1->abc << std::endl; 
... 
+0

請注意,您必須'刪除T1;' – WorldSEnder

+0

@WorldSEnder不能忘記!討厭的指針...:P –

+0

_「反而使用...」_不會導致相同的困境。 –

1
Test* T1 = &Test{ "ghi", 100 }; 

臨時右值Test{ "ghi", 100 }立即超出範圍,並停止該語句之後存在。

因此取消引用它像

cout << T1->abc << endl; 

只是調用一個懸擺指針Undefned行爲

+0

括號內應該是括號嗎?或者有什麼我想念的? –

+0

@OlivierPoulin在當前標準中,可以使用這兩種形式。 –

+0

有意思,謝謝! –

1

這段代碼

Test* T1 = &Test{ "ghi", 100 }; 
cout << T1->abc << endl; //**THIS IS BLANK -- WHY!?** 
cout << T1->x << endl; //THIS GIVES 100 

是未定義的行爲,因爲語句後

Test* T1 = &Test{ "ghi", 100 }; 

臨時對象測試{ 「GHI」,100}將被刪除,指針變爲無效。

一個有效的代碼可以看看下面的方式

Test* T1 = new Test{ "ghi", 100 }; 

cout << T1->abc << endl; 
cout << T1->x << endl; 

delete T1; 

或代替指針,你可以使用一個常量引用到臨時對象。例如,

const Test &T1 = Test{ "ghi", 100 }; 

cout << T1.abc << endl; 
cout << T1.x << endl; 

臨時對象將在活動時存在,而引用將存活。

相關問題