Asked  7 Months ago    Answers:  5   Viewed   41 times

In the following code, when the ctor of X is called will the ctor of A or B be called first? Does the order in which they are placed in the body of the class control this? If somebody can provide a snippet of text from the C++ standard that talks about this issue, that would be perfect.

class A {};
class B {};
class X
 A a;
 B b;



The order is the order they appear in the class definition - this is from section 12.6.2 of the C++ Standard:

5 Initialization shall proceed in the following order:

— First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base class names in the derived class base-specifier-list.

— Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

— Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

— Finally, the body of the constructor is executed. [Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. ]

Tuesday, June 1, 2021
answered 7 Months ago

The order you refer in your question is not the "order of calling base constructor". In fact, you can't call a constructor. Constructors are not callable by the user. Only compiler can call constructors.

What you can do is to specify initializers. In this case (constructor initializer list) you are specifying initializers for subobjects of some larger object. The order in which you specify these initializers does not matter: the compiler will call the constructors in a very specific order defined by the language specification, regardless of the order in which you specify the initializers. The base class constructors are always called first (in the order in which the base classes are listed in class definition), then the constructors of member subobjects are called (again, in the order in which these members are listed in the class definition).

(There are some peculiarities in this rule when it comes to virtual base classes, but I decided not to include them here.)

As for the bad behaviors... Of course there is a potential for "bad behaviors" here. If you assume that the order of initialization depends on the order you used in the constructor initializer list, you will most likely eventually run into an unpleasant surprise, when you discover that the compiler completely ignores that order and uses its own order (the order of declaration) instead. For example, the author of this code

struct S {
  int b, a;
  S() : a(5), b(a) {}

might expect a to be initialized first, and b to receive the initial value of 5 from a, but in reality this won't happen since b is initialized before a.

Saturday, June 19, 2021
answered 6 Months ago


The code is giving the error because the object is not getting created in the second case, and in the first its not initializing, the way its supposed to - Here's the fixed Code:

class A
        static int obj_s;
{  obj_s++;  std::cout << A::obj_s << "nObject(s) Createdn" ;  }

int A::obj_s=0;  // This is how you intialize it

int main()
A a ,b,c,d;
Thursday, August 5, 2021
answered 4 Months ago

(notice: I'm referring to the current C++ standard)

I'm not really sure about this, but, if my interpretation of the standard is correct, the code should be fine and not UB.

The first initialization of that variable is the zero-initialization of objects with static storage duration that happens before any other initialization takes place (§3.6.2 ¶1).

So, first of all i is set to zero.

Then, dynamic initialization (i.e. non-zero and non-constant initialization) takes place, so it uses the current value of i (0) to actually initialize it again. At the end it should evaluate to 1.

This seems confirmed by §8.5 ¶6, that explicitly says:

The memory occupied by any object of static storage duration shall be zero-initialized at program startup before any other initialization takes place. [Note: in some cases, additional initialization is done later. ]

(If you find some flaw in the analysis please just tell me in the comments and I'll be glad to correct/delete the answer, it's slippery floor and I'm conscious of it :) )

Friday, August 13, 2021
answered 4 Months ago

You could create wrapper class which will hold RandomGenerator instance in it and will call RandomGenerator::Randomize in its constructor.

Sunday, August 29, 2021
Martijn Pieters
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :