从构造函数中调用成员函数

Sim*_*ker 12 oop

我知道这个问题与此类似:C++:在构造函数中调用成员函数?但我问的是一个更普遍的问题.

从构造函数中调用成员函数是一种好习惯吗?它使得阅读代码更容易,我更喜欢封装类型的方式(即每个代码块都有一个目标).

python中的一个说明性示例:

class TestClass:
    def __init__(self):
        self.validate()

    def validate(self):
        # this validates some data stored in the class
Run Code Online (Sandbox Code Playgroud)

这是一种比validate在构造函数中编写代码更好的方法吗?这种方法有缺点吗?例如,功能开销是否更昂贵?

我个人更喜欢它的可读性,但这只是我的偏好.

干杯

ric*_*chj 9

我不认为从构造函数调用成员函数有任何固有的错误,前提是它们不是虚函数.

从构造函数调用虚拟成员函数的问题是子类可以覆盖该函数.这将导致构造函数在调用对象的子类部分的构造函数之前调用子类中的重写实现.

在Java中,私有,静态最终访问修饰符中的任何一个都将通过阻止对超类方法的虚拟调用来使方法从构造函数中安全地调用.我认为Python中没有这些技术.


小智 5

您至少应该注意一个相关的“陷阱”:

\n\n

N3797 12.6.2/14

\n\n
\n

可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3)。类似地,构造中的对象可以是运算符typeid(5.2.8) 或 a dynamic_cast(5.2.7) 的操作数。但是,如果在基类的所有mem-initializer完成之前在ctor-initializer中(或在从ctor-initializer直接或间接调用的函数中)执行这些操作,则操作的结果是未定义的。[例子:

\n\n
class A {\npublic:\n   A(int);\n};\n\nclass B : public A {\n    int j;\npublic:\n    int f();\n    B() : A(f()),  // undefined: calls member function\n                   // but base A not yet initialized\n    j(f()) { }     // well-defined: bases are all initialized\n};\n\nclass C {\npublic:\n    C(int);\n};\n\nclass D : public B, C {\n    int i;\npublic:\n    D() : C(f()), // undefined: calls member function\n                  // but base C not yet initialized\n    i(f()) { }    // well-defined: bases are all initialized\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94 结束示例]

\n
\n