Using a parameter and a member variable in a constructor

Each time I write a class constructor, I ask myself whether to use an initialized member variable or constructor parameter. Here are two examples that illustrate what I mean:

Constructor parameter

class Foo { public: Foo(int speed) : mSpeed(speed), mEntity(speed) { } private: int mSpeed; Entity mEntity; } 

Member variable

 class Foo { public: Foo(int speed) : mSpeed(speed), mEntity(mSpeed) { } private: int mSpeed; Entity mEntity; } 

Even more the same problem occurs when using variables in the constructor body.

Constructor parameter

 class Foo { public: Foo(int speed) : mSpeed(speed) { mMonster.setSpeed(speed); } private: int mSpeed; Monster mMonster; } 

Member variable

 class Foo { public: Foo(int speed) : mSpeed(speed) { mMonster.setSpeed(mSpeed); } private: int mSpeed; Monster mMonster; } 

I know that this does not matter (except for some special cases), so I would rather ask for comments on the development of the code than what makes it work and what does not.

If you need a specific question for working with: how is a good and consistent code design obtained, and is there an advantage () in comparison with another?

Edit: Do not forget the second part of the question. What about variables in the constructor body?

+7
c ++
source share
6 answers

I personally prefer to use the constructor parameter to avoid using a non-initialized, but a member variable.

Indeed, in this example:

 class Foo { private: int mEntity; int mSpeed; public: Foo(int speed) : mSpeed(speed), mEntity(mSpeed) { } } 

mEntity initialization will occur before mSpeed ​​initialization (as it was declared earlier). Therefore, you initialize mEntity with non-initialized mSpeed.

-

And inside the constructor body itself, I would also use the constructor parameter, because it is a bit simpler during debugging to see that you are using speed to initialize mMonster, not mSpeed, which itself is initialized by speed. Of course, this is minimalistic overhead, but as we can easily avoid it, I think it's better to do it this way.

+2
source share

I would use the constructor parameter, because when using this initializer, the order in which these initializers are executed is dictated by the order in which the participants were declared, and not by the order in which they are listed. therefore, be careful here.

+3
source share

I would use the constructor parameter. What for? Because of this question. The construtor parameter is clear and readable; you don’t need to know much about C ++ to find out what is going on. Using a member is error prone if you are not sufficiently knowledgeable about C ++ and confuse other people in your team who do not have your level of knowledge, even if you do it right.

If in doubt, keep it simple.

0
source share

You must definitely use the constructor options. As already mentioned, member variables will be initialized in the order in which they were declared in the header file, and not in the order in which they appear in the initialization list.

Some compilers will warn you if the orders do not match, but using constructor options just gives you the least worry. It is easy, for example, to introduce errors this way when you edit the class interface. There is nothing to gain by using member variables to initialize other member variables.

0
source share

I prefer to use a member variable for the case where the parameter should be clamped:

 class Foo { public: Foo(int speed) : mSpeed((speed < 0 ? 0 : speed)), mEntity(mSpeed) { } } 

Thus, if a parameter is invalid, it is not used to ensure that subsequent members are also invalid.

Otherwise, I will stick with the parameter variable.

0
source share

I would also use the constructor parameter. See a simple example:

 // foo.h class Foo { std::unique_ptr<int[]> mBuff; int mSize; public: explicit Foo(int size); // other methods... }; // foo.c Foo::Foo(int size) : mSize(size) , mBuff( std::make_unique<int[]>(size) ) // here using mSize is wrong, // because, mSize is not initialized yet. // here mSize initialized after mBuff, because it declarated after mBuff member. {} 

So, if you use the member parameter instead of the constructor parameter, you can easily create an error situation.

0
source share

All Articles