Is it safe to use the this pointer in an initialization list?
Yes. It's safe to use this
pointer in initialization-list as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly, as the object is not yet fully constructed. The object child
can store the this
pointer of Parent
for later use!
Using this pointer in an initialization list
test(int _a) : this->bse(24) , a(_a) { ... }
is not valid since only member variables and base classes can be initialized in the initializer list. Members of base classes cannot be initialized there.
You have to initialize and/or set the value of the bse
member of the base class using other ways.
Provide a constructor in the base class that takes an
int
. Then, you can use:test(int _a) : base(24) , a(_a) { ... }
Set the value in the body of
test()
.test(int _a) : a(_a) { bse = 24; ... }
Is it safe to pass this pointer in the initializer list in C++?
If the first
variable, in ThirdClass
's constructor is not used, only stored for future use, then this is safe and well defined. If you attempt to use/dereference the pointer in the constructor, then it would be undefined behaviour, since the FirstClass
object has not been constructed yet.
In your example, you wrote:
register for some events here.
that events will call someMethod and someMethod is calling FirstClass's method, before initializer list of FirstClass gets executed.
Since this means that the object's method will be called, then this is likely not valid, and will be Undefined Behaviour, since you cannot call method of an uninitialized object (unless all members that function relies upon are initialized).
passing this from constructor initializer list
If you are extremely careful this will work fine. You will get into a lot of trouble if you start calling virtual methods or using methods which depend on other objects in the type. But if you're just setting a reference this should work fine.
A safer (but not completely safe) alternative is to set b later on once the constructor is completed. This won't eliminate vtable issues but will remove problems like accessing other member variables before they are constructed.
class A : public Callback {
std::auto_ptr<B> spB;
public:
A() {
spB.reset(new B(this));
spB->StartThread();
}
};
using this pointer in initializer list
The code is ambiguous.
For constructing the C
base of F
, the context is direct-initialization, so 13.3.1.3 applies:
c++11
13.3.1.3 Initialization by constructor [over.match.ctor]
For direct-initialization, the candidate
functions are all the constructors of the class of the object being initialized.
The implicitly-declared copy constructor is included, per 12.8:8.
The candidates for the constructor of C
are C(T &)
and (the default copy constructor) C(const C &)
, by parameter list (F)
. In both cases we have a reference binding (13.3.3.1.4) followed by a derived-to-base Conversion (13.3.3.1), with an additional cv-qualification adjustment in the latter case, giving overall rank of Conversion in both cases.
Since C
and T
are both base classes of F
, but are distinct types and neither is a base class of the other, none of the clauses in 13.3.3.2:3 nor 13.3.3.2:4 apply and conversion sequences are indistinguishable.
Indeed, gcc-4.5.1 rejects the code with:
prog.cpp: In constructor 'F::F(const T&)':
prog.cpp:20:34: error: call of overloaded 'C(F&)' is ambiguous
prog.cpp:9:5: note: candidates are: C::C(T&)
prog.cpp:7:1: note: C::C(const C&)
C++: Should I initialize pointer members that are assigned to in the constructor body to NULL?
Generally you only assign it once, in the initialization list or the body, unless the body initialization may or may not happen, or has prerequisite code:
MyClass::MyClass()
{
//this code must happen first
// _now_ max is known
something_ = new Something(max);
}
MyClass::MyClass()
{
if (max)
something_ = new Something(max);
else
something_ = NULL;
}
MyClass::MyClass()
: something_(new Something())
//as pointed out in the comments, use smart pointers
{
}
Member initializer list, pointer initialization without argument
Empty ()
initializer stands for default-initialization in C++98 and for value-initialization in C++03 and later. For scalar types (including pointers) value-initialization/default-initialization leads to zero-initialization.
Which means that in your case m()
and m(nullptr)
will have exactly the same effect: in both cases m
is initialized as a null pointer. In C++ it was like that since the beginning of standardized times.
C++ using this pointer in constructors
The consequence is that the thread can start and code will start executing a not yet fully initialized object. Which is bad enough in itself.
If you are considering that 'well, it will be the last sentence in the constructor, it will be just about as constructed as it gets...' think again: you might derive from that class, and the derived object will not be constructed.
The compiler may want to play with your code around and decide that it will reorder instructions and it might actually pass the this
pointer before executing any other part of the code... multithreading is tricky
Related Topics
C++11 Range-Based For-Loop Efficiency "Const Auto &I" Versus "Auto I"
Portable Text Based Console Manipulator
Is There a C++11 Syntax File for Vim
Using a Static Library in Qt Creator
Version 'Cxxabi_1.3.8' Not Found (Required by ...)
Opencv to Use in Memory Buffers or File Pointers
Purpose of a ".F" Appended to a Number
C++ Implicit Conversion (Signed + Unsigned)
In the Standard, What Is "Derived-Declarator-Type"
How to Write a Stateful Allocator in C++11, Given Requirements on Copy Construction
Ad Hoc Polymorphism and Heterogeneous Containers with Value Semantics
How to Execute a Piece of Code Only Once
How to Write the Following as a C++ MACro
Why Do We Use Std::Function in C++ Rather Than the Original C Function Pointer