views:

304

answers:

3

Hi, Is the following valid?

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;
     ...

   public:
     myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ...
     {
     }
}

Am I right in assuming that the initialization will happen exactly in the order I've given in the ctor? If not, what if m_nDataLength's initialization happens after m_pData's?

+8  A: 

the initialization will initialize fields by order in class, so: if you change

private:
  ...
  int m_nDataLength;
  boost::shared_array<int> m_pData;

as

private:
  ...
  boost::shared_array<int> m_pData;
  int m_nDataLength;

it wont work. In constructor, the order doesn't apply.

Yossarian
+4  A: 

No, initialization for class members happens in the order that the members appear in the class definition. If a member appears in the initializer list, then that controls the expression used to initialize that member (even if it uses a member that has not yet been initialized) but where it appears in the initializer list does not affect when it is initialized.

Charles Bailey
+8  A: 

While the initialization in your example does happen in the order you want, it's not for the reason you assume: Initialization happens in the order of the data members declaration in the class definition. The reason for this is that the destructor must destroy the members in backward order not matter which constructor was used to create the object. For that, a constructor-independent way of defining the construction order must be used.

That means that, if instead of

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;

someone would change your code to

class myClass
{
   private:
     ...
     boost::shared_array<int> m_pData;
     int m_nDataLength;

then the code would have a bug.

My advice is:

  • Write your constructors so that the initialiszation order doesn't matter.
  • If you cannot do this (note: to me this happened less than 5 times in the last decade), make it completely clear at the point the data members are declared.

Something like this should do:

class myClass
{
   private:
     ...
     int m_nDataLength;                 // Note: Declaration order
     boost::shared_array<int> m_pData;  //       matters here!
sbi
Wow, thanks for all the answers here. It has fixed an annoying issue and was an eye-opener for me :)But I voted this one for it's detail.
legends2k