Assign * this to delegate the constructor

I looked at some new features in C ++ 11, and due to my current version of GCC, I cannot use constructor delegation. But it made me think about repeating this function:

class A { public: A() : num( 42 ) {} A( int input ) { *this = A(); num *= input; } int num; }; 

It compiles and works fine of course, the code below:

 A a; cout << "a: " << a.num << endl; A b( 2 ); cout << "a: " << b.num << endl; 

Returns this, which is correct.

 42 84 

Obviously, this is a very trivial example, but besides memory inefficiency (created by two A and one overwritten by the other before destruction), what problems can arise? It certainly sounds like a code smell, but I can't come up with a really good reason.

+4
source share
2 answers

You do not initialize your object with an integer, but modify the default initialized object. This may or may not be a problem. Often people often use common functions in some init() function to have similar functionality as delegation of ctors. However, there are some situations where this is undesirable / incorrect / impossible:

  • when you have a reference element, you must initialize it in ctor, you cannot initialize it by default and rewrite it later. Using a pointer instead may help.
  • for certain members, initialization does something by default, and rewriting does something extra. Performance would be more efficient to immediately initialize a member. Depending on what the initialization does, this may just be a performance hit, but for certain side effects of the object, it may even be wrong.
  • Member cannot be appointed.

In addition, some people consider bad style. I personally think that this is a bad style, because I think you should always initialize, and not assign later, even for simple cases, because one day you will forget about it for an important case, and then the lost performance will bite you.

But YMMV.

+1
source

Your code is actually not C ++ 11. I thought that move constructors could work here, since you essentially move one A to another, and then slightly modify it.

As with C ++ 03, you can optimize the initialization that you want to execute once in all your constructors, or by placing them in a subclass or base class (often with protected or private inheritance, since it is an implementation detail). Using the base class:

 class ABase { protected: int num; ABase() : num(42) {} }; class A : protected ABase { public: A() = default; // or in C++03 just {} explicit A(int input) : ABase() { num *= input; } }; 

(You can change your access rights to taste). The problem here is that I ever create a single "ABase" object, and if it has more than just a trivial int member, it can be significant. I really like inheritance, because then I use it as a member of the class, and not as a member of any aggregate object, and I prefer the inheritance to be protected or closed here, but sometimes, if the base class has members, I want to be public, I use public inheritance, but give the base class a protected destructor. This assumes that there is no v-table, and therefore no further output is expected. (You can finalize A here, actually making inheritance virtual and private, but you probably don't want to).

0
source

Source: https://habr.com/ru/post/1395225/


All Articles