回答
它是有例外做一個設計模式從對象構造函數中拋出。
在C++中,如果從對象構造函數中拋出異常,那麼該對象根據語言運行庫被視爲未構造。 因此,當對象超出範圍時,不會調用對象析構函數。
這意味着,如果你有你這樣的構造函數中的代碼:
int *p1 = new int;
int *p2 = new int;
和這樣的代碼在你的析構函數:
delete p1;
delete p2;
和P2初始化在構造函數中失敗由於沒有更多的可用內存,那麼運算符新的運算符拋出bad_alloc異常。 此時,即使已正確分配了p1的內存,您的對象仍未完全構建。 如果發生這種情況,析構函數將不會被調用,並且正在泄漏p1。
因此,您在構造函數中放置的代碼越多,發生錯誤的可能性就越大,從而導致潛在的內存泄漏。
這是設計選擇的主要原因,畢竟這不是太瘋狂。
更多關於這對香草薩特的博客:Constructors exceptions in C++
這是一個設計選擇。你想讓你的構造函數儘可能簡單,所以很容易閱讀它正在做什麼。這就是爲什麼你會經常看到構造函數調用其他方法或函數,這取決於語言。它允許程序員閱讀並遵循邏輯,而不會在代碼中迷失方向。
隨着構造函數的推出,您可以快速運行一個場景,您可以觸發大量的事件。良好的設計決定了你將這些序列分解爲更簡單的方法,再次使它更易讀,更容易維護。
所以,不,沒有任何傷害或限制,這是一個設計偏好。如果你需要在構造函數中完成所有的初始化,那麼在那裏完成。如果您以後只需要它,請將其放入稍後調用的方法中。無論哪種方式,這完全取決於你,沒有硬性規定或快速規則。
通常對於可維護性,減少代碼大小,當多個構造函數調用相同的初始化代碼:
class stuff
{
public:
stuff(int val1) { init(); setVal = val1; }
stuff() { init(); setVal = 0; }
void init() { startZero = 0; }
protected:
int setVal;
int startZero;
};
在Java中,有充分的理由保持構造短,移動到init()
方法初始化邏輯:
- 構造函數不會被繼承,所以任何子類都必須重新實現它們或提供與
super
- 你不應該調用構造函數重寫的方法,因爲你可以在一個不一致的狀態找到你的目標在那裏部分初始化
你的兩個參數似乎都反對使用'init()'方法。使用'super'清楚地表明你正在初始化基類,'init'可以被覆蓋。事實上'init'可以在派生類中定義是一個非常強烈的反對在基類中使用它的論點。 –
正好相反:它通常是更好地把所有的初始化的 在構造函數中。在C++中,「最佳」策略通常是將 初始化設置在初始化程序列表中,以便成員使用正確的值直接構建,而不是構建默認的 ,然後分配。在Java中,您希望避免函數 (除非它是private
或final
),因爲動態分辨率可以將 放入尚未初始化的對象中。
關於你使用init()
函數的唯一原因是因爲你的 有很多具有顯着通用性的構造函數。 (在C++的情況下 ,你仍然必須權衡默認 建設,然後分配與使用 正確的值近期建設之間的差額。)
如果你有相同的類的多個對象或需要與指針被初始化爲彼此,所以有指針的至少一個週期的不同類別依賴關係,你不能單獨在構造函數中完成所有初始化。 (當另一個對象還沒有被創建時,你將如何構造帶有指向另一個對象的指針/引用的第一個對象?)
這種情況很容易發生的一種情況是在事件仿真系統中,其中不同的組件交互,以便每個組件都需要指向其他組件的指針。
由於無法在構造函數中完成所有初始化,因此至少有一些初始化必須在init函數中發生。這導致了一個問題:在init函數中應該完成哪些部分?靈活的選擇似乎是在初始化函數中完成所有的指針初始化。然後,您可以按照任意順序構造對象,因爲在構建給定對象時,您不必擔心是否已經有必要指向其他需要了解的對象。
- 1. 在構造函數中初始化ArrayList
- 2. 初始化在定義與初始化在構造函數中
- 3. 構造函數中的初始化塊
- 4. 初始化的聲明VS在構造函數初始化
- 5. Java構造函數初始化?
- 6. 初始化構造函數C++
- 7. 創建構造函數初始化
- 8. C++模板構造函數初始化
- 9. 構造函數初始化混淆
- 10. 類的構造函數初始化?
- 11. c#構造函數與初始化
- 12. 長構造函數初始化列表
- 13. 缺少構造函數初始化
- 14. 調用構造函數並初始化
- 15. 初始化列表到構造函數
- 16. 變量初始化和構造函數
- 17. 構造函數初始化和字典
- 18. 初始化類的構造函數
- 19. 用super構造函數初始化()
- 20. 初始化塊vs構造函數vs變量初始化
- 21. 構造函數初始化vs獲取集合初始化
- 22. 帶空初始化的構造函數初始化列表
- 23. C++在構造函數中初始化函數指針
- 24. 在構造函數中初始化靜態函數指針
- 25. 在C++中的類構造函數中初始化列表初始化
- 26. C++重構:初始化在構造函數中排序
- 27. 在類構造函數中初始化結構體
- 28. Java - 私有初始化程序或在構造函數中的初始化?
- 29. 在派生構造函數初始化列表中初始化模板
- 30. 序列化在構造函數中初始化的映射
爲什麼用Java和C++標記?商榷? –
不,但有時會調用init在兩個不同的構造函數之後初始化 - 以避免代碼粘貼。 – Anycorn
虛擬init()可以用於多態初始化 – vid