如果我通過引用調用void setOutputFormat(ostream & out,int decimal_places), ,它將起作用。我不明白爲什麼? 結構和類之間有什麼區別,除了結構成員默認情況下是公共的,並且類成員默認情況下是私有的?爲什麼void setOutputFormat(ostream out,int decimal_places)會導致錯誤?
回答
你說得對,類和結構之間沒有區別,除了默認的私有和私有。
這裏的問題是,ostream沒有拷貝構造函數,所以你不能通過值來傳遞它。
當試圖通過值的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
修改就地原始流的唯一途徑。希望這可以澄清這個問題。
正如其他人所說,你試圖創建一個不可複製的對象(流)的副本,從而導致該錯誤。在C++中,當你傳遞一個var作爲參數時,你需要複製它(與C#相反,其中,對於引用類型,你總是隱含地將引用傳遞給它)。
默認情況下,C++爲每個類都提供了一個按位拷貝構造函數,但通常不是這麼做的:例如,想一下擁有資源句柄的類:如果您完全克隆了該類型的對象你會有兩個階級認爲擁有這樣的資源,並且兩個階級都會試圖在毀滅時摧毀它,這顯然不好。
正因爲如此,C++,您可以爲每個類,其被稱爲當對象的一個副本,必須創建提供拷貝構造。由於許多對象(包括流)都不需要創建副本(因爲它沒有意義,因爲它不方便,或者因爲麻煩不值得工作),因此經常會禁用副本構造函數(將其標記爲private
或protected
),並且您不能創建這些對象的副本。
此外,一般來說,您必須小心使用屬於複雜類層次結構的對象進行賦值和複製,因爲您可能會遇到對象切片和其他細微問題。實際上,通常的做法是阻止複製和賦值作爲基類的類。
在大多數情況下(包括你的),解決方案是通過引用傳遞這些對象,從而避免複製;請參閱@Jon Purdy的答案爲例。順便說一下,通常即使對於可複製對象(例如std::string
s),最好只傳遞引用,以避免與複製相關的所有工作;如果您只是爲了提高效率而傳遞引用,但不希望修改對象,那麼最佳解決方案通常是const
引用。
副本也用在C++的其他地方;我建議你看一下wikipedia page關於拷貝構造函數,以更好地理解發生了什麼,但總的來說,抓住一本C++書籍並閱讀它:C#在很多方面與C++不同,並且有很多假相似可能會讓你感到困惑。
- 1. 爲什麼它會導致錯誤?
- 2. 爲什麼會導致段錯誤?
- 3. 爲什麼這會導致SIGABRT錯誤?
- 4. PDO:爲什麼會導致錯誤?
- 5. 爲什麼這會導致錯誤?
- 6. 爲什麼會導致「exc_bad_access」錯誤?
- 7. 這爲什麼會導致StackOverFlow錯誤?
- 8. .val()爲什麼會導致錯誤?
- 9. 爲什麼vmovapd會導致段錯誤?
- 10. 爲什麼CPPUNIT_ASSERT_MESSAGE會導致OpenMP錯誤?
- 11. 爲什麼uint8_t + uint8_t會導致int?
- 12. List <T> as'out'參數會導致錯誤。爲什麼?
- 13. 基本Java Gui錯誤:爲什麼JButton會導致錯誤?
- 14. 爲什麼這個指針操作序列會導致錯誤?
- 15. 爲什麼$ {z $ i} = $ line會導致「錯誤替換」錯誤?
- 16. 爲什麼編譯此代碼會導致語法錯誤?
- 17. 爲什麼「導入javax.jdo。*」導致錯誤?
- 18. pthread_join導致分段錯誤。爲什麼?
- 19. 什麼會導致404錯誤消耗?
- 20. 什麼會導致此SIGSEGV錯誤?
- 21. 什麼會導致UnhandledAlertException錯誤?
- 22. void(int)和void(*)(int)有什麼區別?
- 23. 爲什麼在golang中打印出max int會導致編譯錯誤?
- 24. 爲什麼StreamReader.readexactly()會導致套接字錯誤,但不會導致StreamReader.read()?
- 25. 這爲什麼合併排序會導致錯誤的結果?
- 26. 爲什麼這是')'導致錯誤?
- 27. 爲什麼添加文字會導致玩家移動錯誤?
- 28. 爲什麼此數組分配會導致段錯誤?
- 29. 爲什麼簡單地鏈接到GL會導致段錯誤?
- 30. 這爲什麼會導致分段錯誤?
什麼是複製構造函數?對不起,我來自C#,這對我來說是種倒退 – 2010-09-25 21:56:34
@ cable729:如果你不知道什麼是拷貝構造函數,你是在向後做。我們不能在Q&A網站上教你C++。請參閱[本](http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books)瞭解接下來要做什麼。 – sbi 2010-09-25 21:58:43