Any class member that's not explicitly initialized in the constructor's member initializer list is default-initialized before the constructor's body is entered. For members of class type, that means default-constructed:
CFoo::CFoo() // : m_CBar() <--------- The constructor behaves as if you wrote this* { InitializeCriticalSection( &m_CriticalSection ); m_IsInitialized = FALSE; m_CBar = CBar(15); }
Thus, at m_CBar = CBar(15);, you are assigning a temporary instance of CBar, constructed with CBar(15), to m_CBar, which invokes the assignment operator.
It's usually better to construct m_CBar in the member initializer list:
CFoo::CFoo() : m_CBar(15) // Directly constructs m_CBar, passing 15 to the CBar constructor { InitializeCriticalSection( &m_CriticalSection ); m_IsInitialized = FALSE; }
*: m_CBar() actually value-initializes m_CBar, which does the same thing as default-initialization in cases where, like here, m_CBar is of class type with a user provided constructor. In cases involving scalar types or classes with no user-supplied constructor, value-initialization will cause a zero-initialization (followed by invocation of any nontrivial implicit default constructor for something of non-union class type) to take place, while default-initialization does not cause a zero-initialization. You can find all the fun details with the definitions of all three kinds of initialization (zero, default, and value) in §8.5[dcl.init] of the C++11 standard.†
† C++14 made some changes to these rules, which plug some holes in certain edge cases. The most important change though is that objects with an explicitly defaulted default constructor are now always treated the same way as objects with an implicitly defined default constructor (and hence always first zero-initialized before the default constructor, if nontrivial, is invoked), regardless of whether it also has other user-provided constructors.
CBarthat's used to construct the temporary on the rhs of the assignment).m_CBarhas already been initialized, so you can only have assignment. There's no mystery here.m_CBarisn't in a member initializer list, it's default-constructed before you enter the constructor body.