TICS Coding Standard Viewer 
TIOBE Software Quality Framework
Print-friendly version
©TIOBE Software www.tiobe.com
 
C++ Coding Standard
Search

Rule:  OLC#019Checked automatically with code checker

Synopsis:If passing the "this" pointer to a constructor initializer list, be aware that the object is not yet fully constructed
Language:C++
Severity Level:5
Category:Object Life Cycle


Description:

The "this" pointer can be used in the constructors list of initializers for base classes and member variables. While doing so is valid, you must ensure that those base classes and member variables do not use the passed in "this" pointer to access parts of this object until those parts have been initialized sufficiently. In particular, any virtual functions should not be called until the rest of the initializer list and the most necessary parts of the constructor code have been executed, nor should any members of *this be accessed until those particular members have been initialized.

Example (wrong):

class CC;

class B {
    int &r_x1;
  public:
    B(CC *c);
};

class CC {
  public:
    B b;
    int &r_x2;
    CC(int &i): r_x2(i), b(this) {} // Violation! 
};

B::B(CC *c): r_x1( c->r_x2 ) {
}

This will crash because b is initialized before r_x2, because the B constructor assumes that r_x2 can be safely duplicated into r_x1, neither of which is true until after r_x2 is initialized.

Example (right):

class A {
   int m_x;
   class A_xWrap {
      A& parent;
     public:
      A_xWrap(A* pParent): parent(*pParent) {}
      A_xWrap & operator = (int x) { parent.x_Put(x); return *this; }
      int operator int (void) const { return parent.x_Get(); }
   }
  public:
   A_xWrap x;
   A() : x(this), m_x(2) { } // OK
   int x_Get(void) { return m_x; }
   void x_Put(int i) { if (i>= 0) x = i; }
};

This is safe because A_xWrap does not access this until something after this constructor returns tries to use the x field as if it was the m_x field.



Literature References:
ISC++ Rec. 5.7