回答
它是有例外做一个设计模式从对象构造函数中抛出。
在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