C++智能指针构造函数中给类成员赋值0的行为解析及初始化写法疑问
Great question—smart pointers and C++ initialization rules can feel overwhelming when you're just starting out. Let's break this down clearly.
What happens when assigning 0 to pData and reference?
In C++, assigning 0 to a pointer variable (or initializing it with 0 in the member initializer list) sets that pointer to a null pointer. This means the pointer doesn't point to any valid memory address—it's a "non-existent" pointer.
Looking at your original constructor:
SP() : pData(0), reference(0) { reference = new RC(); reference->AddRef(); }
Here's the step-by-step flow:
- First, the member initializer list runs:
pDatais initialized to a null pointer, andreferenceis also initialized to a null pointer. - Then the constructor body executes:
reference = new RC();creates a newRCobject on the heap, and overwrites the null pointer value ofreferencewith the address of this new object.reference->AddRef()calls theAddRefmethod on the newRCinstance, incrementing itscountmember by 1.
A quick side note: In C++11 and later, nullptr is the preferred way to represent null pointers (it's type-safe, unlike 0 which can be confused with integer values). So pData(nullptr) is better than pData(0).
Why not use the direct initializer list approach?
Your suggested simplified constructor:
SP() : pData(0), reference(new RC())
is actually more efficient and cleaner than the original code. Here's why the original approach is redundant:
- The original code first initializes
referenceto0(a null pointer) in the initializer list, then immediately overwrites that value withnew RC()in the constructor body. This is unnecessary—you're doing extra work to set the pointer to null just to replace it right away.
The only catch: The original constructor also calls reference->AddRef(), which can't be done directly in the initializer list (initializer lists are only for initializing members, not for calling member functions). So the optimized, correct version would be:
SP() : pData(nullptr), reference(new RC()) { reference->AddRef(); }
So why might someone write the original code? A few possible reasons:
- They might not fully understand how member initializer lists work, and default to initializing variables to "safe" null values before assigning their actual values.
- The code might have been modified from an older version where the null initialization was necessary, and the redundant step wasn't cleaned up.
- They might not realize that initializing a pointer directly to the result of
newis safe and efficient.
Remember: In C++, member variables are initialized in the order they're declared in the class (not the order they appear in the initializer list). In your SP class, pData is declared first, then reference, so your initializer list order is correct here.
内容的提问来源于stack exchange,提问作者Scorpia

