2010-09-25 38 views

回答

3

你說得對,類和結構之間沒有區別,除了默認的私有和私有。

這裏的問題是,ostream沒有拷貝構造函數,所以你不能通過值來傳遞它。

+0

什麼是複製構造函數?對不起,我來自C#,這對我來說是種倒退 – 2010-09-25 21:56:34

+7

@ cable729:如果你不知道什麼是拷貝構造函數,你是在向後做。我們不能在Q&A網站上教你C++。請參閱[本](http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books)瞭解接下來要做什麼。 – sbi 2010-09-25 21:58:43

2

當試圖通過ostream通過,你試圖讓流,因爲流對象是不可複製這是無效的副本,也就是說,它們不定義副本構造函數。然而,當您通過參考傳遞流時,該功能會收到一個可修改的別名ostream實例。就拿:

void increment(int n) { 
    // Increment local copy of value. 
    ++n; 
} 

int x = 5; 
increment(x); 
// x is still 5. 

對戰:

void increment(int& n) { 
    // Increment value itself. 
    ++n; 
} 

int x = 5; 
increment(x); 
// x is now 6. 

因此,通過引用傳遞流是有道理的,因爲你要setOutputFormat修改就地原始流的唯一途徑。希望這可以澄清這個問題。

0

正如其他人所說,你試圖創建一個不可複製的對象(流)的副本,從而導致該錯誤。在C++中,當你傳遞一個var作爲參數時,你需要複製它(與C#相反,其中,對於引用類型,你總是隱含地將引用傳遞給它)。

默認情況下,C++爲每個類都提供了一個按位拷貝構造函數,但通常不是這麼做的:例如,想一下擁有資源句柄的類:如果您完全克隆了該類型的對象你會有兩個階級認爲擁有這樣的資源,並且兩個階級都會試圖在毀滅時摧毀它,這顯然不好。

正因爲如此,C++,您可以爲每個類,其被稱爲當對象的一個​​副本,必須創建提供拷貝構造。由於許多對象(包括流)都不需要創建副本(因爲它沒有意義,因爲它不方便,或者因爲麻煩不值得工作),因此經常會禁用副本構造函數(將其標記爲privateprotected ),並且您不能創建這些對象的副本。

此外,一般來說,您必須小心使用屬於複雜類層次結構的對象進行賦值和複製,因爲您可能會遇到對象切片和其他細微問題。實際上,通常的做法是阻止複製和賦值作爲基類的類。

在大多數情況下(包括你的),解決方案是通過引用傳遞這些對象,從而避免複製;請參閱@Jon Purdy的答案爲例。順便說一下,通常即使對於可複製對象(例如std::string s),最好只傳遞引用,以避免與複製相關的所有工作;如果您只是爲了提高效率而傳遞引用,但不希望修改對象,那麼最佳解決方案通常是const引用。

副本也用在C++的其他地方;我建議你看一下wikipedia page關於拷貝構造函數,以更好地理解發生了什麼,但總的來說,抓住一本C++書籍並閱讀它:C#在很多方面與C++不同,並且有很多假相似可能會讓你感到困惑。

相關問題