C++已在构造函数初始化列表初始化成员变量,头文件仍需用nullptr/Q_NULLPTR初始化吗?
Great question! Let's break down why that in-class initialization (QDialog* m_Dialog = Q_NULLPTR;) is still important, even though you're properly initializing and cleaning up the pointer in your constructor and destructor.
1. It prevents undefined behavior if your constructor throws an exception
Suppose the new QDialog() call in your constructor initialization list throws an exception (for example, if there's not enough memory to allocate the dialog). If you didn't have the in-class initialization, m_Dialog would be left in an uninitialized state—it would hold a random garbage value.
When the exception propagates and the object's destructor runs (yes, even partially constructed objects get their destructors called for members that were initialized), your destructor would try to delete that garbage value. Deleting an uninitialized pointer is undefined behavior—it could crash your program, cause memory corruption, or do something completely unpredictable.
With the in-class initialization, m_Dialog is set to Q_NULLPTR (equivalent to C11's nullptr) before the constructor initialization list even runs. Even if new QDialog() fails, m_Dialog is still a valid null pointer, and delete nullptr is perfectly safe in C (it does nothing, no harm done).
2. It acts as a safety net for multiple constructors
If your class ever gets additional constructors (say, a copy constructor, a move constructor, or a constructor with different parameters), it's easy to forget to initialize m_Dialog in the initialization list of the new constructor. Without the in-class default, that would leave the pointer uninitialized, leading to the same undefined behavior risks as above.
The in-class initialization ensures that no matter which constructor is used, m_Dialog starts with a valid null value—you only need to override it in the initialization list when you want to assign a non-null pointer.
3. It improves readability and consistency
Putting the default value directly in the header makes it immediately clear to anyone reading the code that this pointer starts as null. You don't have to hunt through all constructor implementations to find out its initial state.
Plus, using Q_NULLPTR aligns with Qt's coding conventions, making the code feel consistent with other Qt-based projects.
One quick note: The constructor initialization list (m_Dialog(new QDialog())) will override the in-class default value, so your pointer will correctly point to the new QDialog instance when the constructor completes successfully—you're not wasting any initialization work here.
内容的提问来源于stack exchange,提问作者Sayan Bera

