构造函数正确的写法是什么?两段式的构造函数

如何写出一个合理的构造函数,因为构造函数内部可能会有内存分配错误等问题。我所知的有两种处理方法。 
1.在构造函数里抛出异常。 
2.两段式的构造函数,就是说有一个init()的函数,专门负责内存分配等复杂的操作,然后建立一个m_isinit的变量记录是否已经初始化。 
这两种方法哪一种较好,或者说有不同的应用场合?还是有其他的更好的写法呢? 
还有C++和JAVA两种语言的是否有不同写法?

以下描述适用于Java和C++

构造函数的基本职责之一,是对所有的类成员变量进行初始化, 让你的对象初始化后处于一个可用的状态(Good State)。至于是否能够在构造函数里面抛出异常,有时候是在于团队。实际情况是,有些开发团队不喜欢使用异常,或者大部分人不善于处理异常,这个时候是可以彻底去掉异常的使用。异常也是C++常见的争论之一,我就不在这里“挑事儿”了。

在C++的构造函数中使用异常是完全可以的,但是我个人习惯是不在构造函数中抛出异常,因为C++不同于Java,没有强制你处理异常的机制,别人使用你编写的类的时候,常常不会去看你的文档或者代码。不在构造函数里面抛出异常,仅仅是为了避免不必要的沟通成本。当然,如果团队管理得当,代码规范执行得彻底,完全是可以不这么做的。

写构造函数的另外一个原则是在构造函数里尽量做最少的工作,Bjarne Stroupstrups在 cise.ufl.edu/~manuel/st 中提到的"Deplay Acquisition"就是这个原则。任何不必要的资源都可以在需要时才申请使用。 设计类的时候,要反复问自己,真的有必要在构造函数里面申请内存吗?如果有必要,请参考Bjarne Stroupstrups在这个slide中的例子。

基于上面原则的延伸,在Java中,写构造函数的另外一个原则是不要在构造函数中调用本类的其他pubilc/protected函数,因为在Java中,一旦调用的函数被子类覆盖,可能会导致不可预知的问题。感谢@brooks提醒,“构造函数中虚函数是不能多态的,如同调用非虚函数,调用的动机值得怀疑。”。

因此,对于问题中提到的两段式初始化方法,我的意见是可以不要,如果一定要用,建议把它声明成"private"。


作者:孙立伟
链接:https://www.zhihu.com/question/19892225/answer/14085667
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(C++)