I am learning about inheritance in C . And i came across the following statement:
In other words, the this pointer cannot be aliased in a constructor:
extern struct D d;
struct D
{
D(int a) : a(a), b(d.a) {} // b(a) or b(this->a) would be correct
int a, b;
};
D d = D(1); // because b(d.a) did not obtain a through this, d.b is now unspecified
The above example is from cppreference.
My first question is that it is written that "this
cannot be aliased in a ctor" but then in the example above, they've written in the comment "b(this->a)
would be correct". This seems to be a contradiction to me because when they said that this
cannot be aliased in a ctor i understood that "this
cannot be used in a ctor". But then why are they saying that writing b(this->a)
would be correct if this
cannot be used/aliased in a ctor. Isn't the initializer list considered "in a ctor"?
Now lets look at a custom example:
struct Name
{
private:
int x = 0;
Name(int n )
{
this->x = 4; //is the use of "this" well-defined here?
}
};
My second question is that is the use of the expression this->x
inside the converting constructor shown above well-defined? I mean since according the quote at the beginning of my question this
can't be aliased in a ctor, so this shouldn't be valid.
CodePudding user response:
What is meant is that during the construction of a class object any access to the object's non-static data members should happen through a pointer/glvalue obtained directly or indirectly from this
of the constructor. Otherwise the value read by such an access is unspecified.
So this->a
is always fine, as is simply a
which is implicitly the same as this->a
.
It is also ok to copy the pointer this
and access members through that, e.g.
auto p = this;
b = p->a;
or to store a reference to the object:
auto& r = *this;
b = r.a;
But in the example given at the beginning, d
is the same object as this
points to. In other words the name d
and *this
are aliases for the same object. It is not allowed to use this other alias d
to access non-static data members of the class while it is under construction because d
was not obtained from this
. Or to be more precise, it is unspecified what value such an access will read. So b(d.a)
may or may not initialize the b
member to the same value as a
.
See [class.cdtor]/2.