在C++中,构造函数中的成员初始化列表(member initializer list)和构造函数体(constructor body)中进行的初始化存在显著的不同。这种不同主要体现在初始化时机、效率和语义上。
成员初始化列表(Member Initializer List)
在你的示例中,CMotorCtrl
的构造函数使用了成员初始化列表来初始化成员变量。这是通过在构造函数定义中的冒号:
后面列出的。
cpp复制代码
CMotorCtrl::CMotorCtrl(CWnd* pParent /*=nullptr*/) | |
: CDialog(IDD_DIALOG_CTRL, pParent) | |
, m_strCH1(_T("")) | |
, m_strCH2(_T("")) | |
, m_strCH3(_T("")) | |
, m_strCH_Addr(_T("")) | |
, m_nSlider1(0) | |
, m_Addr(1) | |
, m_mode_ch1(0) | |
, m_mode_ch2(0) | |
, m_mode_ch3(0) | |
, m_Test_Start(0) | |
, m_strRunPeriod(_T("200")) | |
{ | |
// 构造函数体 | |
memset(&m_MasterCtrl, 0x00, sizeof(m_MasterCtrl)); | |
m_UpdateFlag = 0; | |
m_RunCounter = 0; | |
} |
- 初始化时机:成员初始化列表中的初始化是在调用基类构造函数和成员变量构造之前完成的。这意味着它们发生在对象实际构造的早期阶段。
- 效率:对于内置类型(如
int
、float
等)和简单的类类型,使用成员初始化列表通常比在构造函数体内赋值更高效,因为它避免了先默认构造再赋值的开销。 - 语义:对于某些类型(如引用和
const
成员),只能使用成员初始化列表进行初始化,因为它们在构造函数体内不能被赋值。
构造函数体(Constructor Body)
构造函数体中的代码(即大括号{}
内的代码)在成员初始化列表之后执行。
- 初始化时机:构造函数体内的代码在成员初始化列表之后执行,这意味着它发生在对象构造的后期阶段。
- 用途:通常用于执行更复杂的初始化逻辑,或者调用成员函数来初始化对象状态。
- 注意事项:在构造函数体内,可以修改已经通过成员初始化列表初始化的成员变量的值,但这可能会覆盖之前的初始化。
总结
在你的例子中,m_strCH1
、m_strCH2
等字符串变量和m_nSlider1
、m_Addr
等内置类型变量通过成员初始化列表进行初始化,这是推荐的做法,因为它们避免了不必要的默认构造和赋值开销。而m_MasterCtrl
等复杂类型或数组可能需要在构造函数体内使用memset
或其他方式进行初始化,因为它们可能需要更复杂的初始化逻辑。