views:

63

answers:

5

Here is some C++ code:

#include <iostream>
using namespace std;

class m
{
    public:
    m() { cout << "mother" << endl; }
};

class n : m
{
    public:
    n() { cout << "daughter" << endl; }
};

int main()
{
    m M;
    n N;
}

Here is the output:

mother  
mother  
daughter

My problem is that I don't want the m's constructor to be called when I create N. What should I do ?

A: 

Two solutions:

  1. Don't derive n from m. Check that you really have interface reuse (that you rely on a polymorphic interface) instead of implementation reuse. In the latter case, prefer making an m* a member of n and then only create the m object when needed. This would be my preferred solution.

  2. You probably don't want ms contructor to be called because it does something which you don't want. Move that code which you don't want to execute out of ms constructor into a dedicated init() function or the like, and then call it as needed. I don't recommend this because you end up with a stateful interface.

Frerich Raabe
+1  A: 
class m
{
public:
      m(bool init = true) { if (init) cout << "mother" << endl; }
};


class n : m
{
public:
      n() : m(false) { cout << "daughter" << endl; }
};

or if you don't want it to be public

class m
{
protected:
    m(bool init) { if(init) Init(); }
    Init() { cout << "mother" << endl; }

public:
      m() { Init(); }
};

class n : m
{
public:
      n() : m(false) { cout << "daughter" << endl; }
};
adf88
+5  A: 

AFAIK, you cannot remove inherited constructor.

The problem in your example comes from incorrect class design. Constructor is normally used for allocating class resources, setting default values, and so on. It is not exactly suitable to be used for outputting something.

You should put

n() { cout << "daughter" << endl; }

Into virtual function.

In general - if you have a need to remove inherited constructor, then you probably need to rethink/redesign your class hierarchy.

SigTerm
+1 but to avoid leading the OP astray, perhaps it should be pointed out that ctors should not call virtual functions.
Beware that the dynamic type of the object changes while the object is being constructed. If you make the call to the virtual method within the base constructor the output will always be 'base' as when that constructor is being executed the object **is** a 'base'
David Rodríguez - dribeas
@stinky472: In C++, unlike Java, it is safe to call a virtual method in the constructor (or destructor) as long as you know that at this point deriving classes overriders will not be considered. Only if the method is pure virtual at this level, it is undefined behavior calling it from the constructor/destructor. In Java, in the other hand, you *must not* call any overriden method in the constructor as that will be dispatched to the most derived class that has not yet been initialized.
David Rodríguez - dribeas
A: 

Constructors are never inherited. What happens is that C++ generates a default nullary constructor that initializes the base classes and members of class type. The base classes are always initialized and there is no way to prevent this, so if you don't want the base class constructors to be called, don't inherit from the base class.

Philipp
A: 

Object of any class contains in it sub-objects of all its superclasses. And all of them must be constructed before construction of main object. Part of this construction is calling one of base class constructors and it cannot be omitted. You can only choose constructor to be called.

Tadeusz Kopec