How to maintain order of class members and still have a working constructor

static initialization order fiasco
c++ class member variable initialization
c++ static initialization order
c++ constructor
constructor initializer list
c++ constructor initializer list order
how to initialize a class member in c++
c++ initialization order

I want to have tidy header files, where puiblic members are listed first, then private members.

class A
{
public:
    A() : y(0), z(0), x(y + z)
    {}

    int x;

private:
    int y;
    int z;
};

Members are initialized in the order they are declared, so this constructor is buggy because y and z are not initialized when x is using them.

This is just an example where I could write x(0), but if these weren't ints but bigger types, then it would be cumbersome. To get around this I would need to first list privete members y and z, then public member x. Is there any way that I can leave my private members at the bottom whilst initializing them first in the initializer list?

If not, please guide me to how I should order members, because I can't find any examples of this online. First listing some public, then some private, then more public members seems dirty to me but maybe I'm wrong.

C++, as a language, doesn't do a great job of keeping implementation details out of header files, or separate from the interface in general. Anything you do here is going to be a compromise.

One hard-line approach would be to not have any public member variables, and for that matter to separate and expose a pure virtual interface (in a separate file). At that point, the actual class wouldn't even need to be in a header -- just in a source file, referred to by a factory function -- so the remaining header is as clean as you'd like. This is not an approach I'd recommend.

In any case, there are various practical considerations in C++ which constrain the order of class members. Putting all the public members at the top of the class is a good plan A, but sometimes it's not going to work out, and I wouldn't suggest that you go to any heroics to make it work out.

Constructors, C++ FAQ, Can one constructor of a class call another constructor of the same class to initialize Do I need to worry about the “ static initialization order problem” for variables of If that doesn't work, e.g., if there isn't an appropriate default parameter that however if you ever use the data member, you still need to explicitly define it in� Order of Constructor Call with Inheritance in C++. Base class constructors are always called in the derived class constructors. Whenever you create derived class object, first the base class default constructor is executed and then the derived class's constructor finishes execution.

Using a delegating constructor you can write this as:

class A
{
public:
    A() : A(0, 0) { }
    {}

    int x;

private:
    explicit A(int y_, int z_) : x(y_ + z_), y(y_), z(z_) { }
    int y;
    int z;
};

Understanding Class Members (The Java™ Tutorials > Learning the , Sometimes, you want to have variables that are common to all objects. At the same time, you need a field to keep track of how many Bicycle objects have been created You can use the Bicycle constructor to set the id instance variable and � The Class Constructor. A class constructor is a special member function of a class that is executed whenever we create new objects of that class. A constructor will have exact same name as the class and it does not have any return type at all, not even void. Constructors can be very useful for setting initial values for certain member variables.

Is there any way that I can leave my private members at the bottom whilst initializing them first

No. Members are initialised in order of declaration; there is no way around that.

If you just want the members somewhere other than the top of the class, then you could use a base:

struct B {
    int y;
    int z;
};


class A : B
{
public:
    A() : B{0, 0}, x(y + z)
    {}

    int x;
};

First listing some public, then some private, then more public members seems dirty to me but maybe I'm wrong.

That's not necesasry in your case, as you can put all private stuff first and then all public. But in general, splitting declarations with same access specifier is just fine; although rarely necessary.

Constructors (C++), To customize how class members are initialized, or to invoke functions when an A constructor has the same name as the class and no return value. The compiler-generated copy constructor simply copies the pointer, so that the new pointer still points to the A constructor performs its work in this order:. For example, all members of class type, and their class-type members, must have a default constructor and destructors that are accessible. All data members of reference type, as well as const members must have a default member initializer. When you call a compiler-generated default constructor and try to use parentheses, a warning is issued:

The problem is that X is dependent on Y and Z, but Y and Z are knowns. Possible ways you could look to solve this:

(1) Pass in a constructed X, instead of having the constructor make it.

int y = 1;
int z = 40;
int x = y + z;
A(y, z, x);

(2) A more wild idea, (please don't do this, it typically indicates a problem with how you've factored your code). Create a default object and then use placement new. However, when I see code like this, it's typically using an init() function or something. It's super overkill for ints, but I'm assuming that you have a more complex type which is why you're doing it.

A() : y(0), z(0), x(/*default construct*/)
{
  new (&x) int(y + z);
}
//or
A() : y(0), z(0), x(/*default construct*/)
{
  x.init(y, z);
}

Overall, I think you should re-evaluate why X depends on Y and Z, and maybe shuffle some data and responsibilities around.

If X depends on the state of Y and Z, you might want to make it a function instead if it's used outside of the class, because as a public member variable other people could modify it and possible de-sync it from X and Y. You might also want to put Y and Z inside of X instead.

OOP53-CPP. Write constructor member initializers in , The member initializer list for a class constructor allows members to be Then, direct base classes are initialized in declaration order as they appear in the OOP53-CPP-EX0: Constructors that do not use member initializers do not violate this rule. While I agree that we could clarify the normative wording, I still think the� He calls the default constructors of all the members, if you don't explicitly tell him to use non-default constructor for a given member. – Steed May 15 '12 at 12:56 But note that plain data types (int, double, etc) do not have a constructor, so their memory remains uninitialized.

C++ Core Guidelines, Or better still just use the type system and replace Int with int32_t . Note that it is possible to get undefined initialization order even for const objects. a constructor and must be reestablished upon exit by every member function The rule Keep functions short and simple implies “Keep loop bodies short. As you know, private and protected data members can be accessed outside the class by using public member functions of the class. C++ offers a special function, called constructor, which makes the initialization of an object. A constructor is a special function that is called every time you create an object.

member-ordering, A consistent ordering for class members can make classes easier to read, practice to member-ordering is to keep related groups of classes together. Instead The order property should have a value of one of the following strings: fields-first puts, in order of precedence: * fields before constructors before methods * static� A constructor in C# is a member of a class. It is a method in the class which gets executed when a class object is created. Usually we put the initialization code in the constructor. The name of the constructor is always is the same name as the class. A C# constructor can be public or private. A class can have multiple overloaded constructors.

C# Constructor: Usage, Examples, Best Practices, and Pitfalls, To define “C# constructor,” let's first see what Wikipedia has to say We're still using the Person class from the first example, but we've changed it a bit. constructor in order to prevent classes that only have static members when working with constructors, and also some pitfalls you need to be aware of. Constructor is used for initializing the instance members when we create the object of a class. For example: Here we have a instance variable num which we are initializing in the constructor. The constructor is being invoked when we create the object of the class (obj in the following example).

Comments
  • The simple way is to not have members rely on each other. Having them do so makes the code brittle and more prone to bugs.
  • Why not declaring x as zero and use the constructor to add y and z ?
  • your example isnt the best. For this specific example the fix would be to simply initialize x(0), no reason to make it more complicated than necessary
  • also note that c++11 introduced delegating constructors, i never used them myself, but I would guess that they help to circumvent the problem
  • You can move y,z to a private base.
  • This is a good way to solve the problem as stated, but I just want to observe that classes that mix and match public data (no invariants can be supported) and private data (class interface enforces invariants) will make classes somewhat to significantly harder to read/maintain in the future.
  • That's what delegating constructors are for. Using in-place new is dirty.
  • Hence my warning. In-place new in general outside of a memory manager or buffering system in general indicates a severe problem somewhere.
  • I'm 99% sure that x in this case should just be a calculated value, or y and z belong in x with possible accessors. Without seeing the actual code I don't know for sure though.