user2261693
user2261693

Reputation: 405

Inherit constructor

I have a class named myGraph which is derived from graph

If I know the number of vertices when I call the constructor, I will be able to use the following constructor.

myGraph(int numOfV) : graph(numOfV)
{
    // initialize...
}

I want to compute the number of vertices in the constructor and then inherit graph inside the constructor. How to do so?

myGraph(int a, int b)
{
    /* using a,b to initialize...  
       a sequence of push operation on (vector<T>)verticeList */

    int numOfV = this->verticeList.size();
    // inherit...
    myGraph(numOfV);  // it will not work


}

Please note that

  1. the procedure I use to compute the number of vertices is complicated.(many lines of code rather than a+b)

  2. the number of vertices depends on the instance variables in myGraph, so I need to initialize the members of myGraph first and then inherit the remaining graph part.

Upvotes: 2

Views: 251

Answers (4)

Arne Mertz
Arne Mertz

Reputation: 24576

the number of vertices depends on the instance variables in myGraph, so I need to initialize the members of myGraph first and then inherit the remaining graph part.

That is not possible. Base classes are always initialized before data members. However, during construction the values you assign to your members depend solely on the constructor arguments, so the base class' constructor parameters depend only on those arguments as well.

Let's say you have members m1 and m2 and want to initialize the base class with values dependent on those two members, say f(m1,m2) and g(m1,m2). Your constructor has the parameters a, b, c and you initialize m1 and m2 dependent on those ctor arguments, with x(a,b,c) and y(a,b,c). Then the ctor should look like this:

class Foo : Bar {
  int m1;
  int m2;
  static int x(int a, int b, int c);
  static int y(int a, int b, int c);
public:
  Foo(int a, int b, int c) 
    : Bar( f(x(a,b,c), y(a,b,c)), g(x(a,b,c), y(a,b,c)) )
    , m1(x(a,b,c))
    , m2(y(a,b,c)) 
  {}
};

Of course, to improve readability, you can always create more static functions to calculate the initializer for the base object:

class Foo : Bar {
  /* ... */
  static Bar calcBar(int a, int b, int c) {
    int i1 = x(a,b,c);
    int i2 = y(a,b,c);
    return Bar(f(i1,i2), g(i1,i2));
  }

public:
  Foo(int a, int b, int c) 
    : Bar( calcBar(a,b,c) )
    , m1(x(a,b,c))
    , m2(y(a,b,c)) 
  {}
};

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258568

If there's a lot of logic going on pre-initialization, you can separate that in a method:

struct myGraph
{
    myGraph(int a, int b) : graph(myGraph::computeNoVertices(a,b))
    {
    }
    static int computeNoVertices(int a, int b)
    {
        //whole chunk of code 
    }
};

Upvotes: 3

Vaughn Cato
Vaughn Cato

Reputation: 64308

With C++11, you can do a limited amount of this:

myGraph(int a, int b)
  : myGraph(a+b)
{
}

If your calculations are much more sophisticated, you'll want to break them out into a separate function though:

myGraph(int a,int b)
  : myGraph(calculateNumOfV(a,b))
{
}

Upvotes: 1

taocp
taocp

Reputation: 23624

You have to call base class constructor at derived class's member initialization list:

 myGraph(int a, int b) :graph(a +b)
 {                     //^^It is OK to do computation when you pass parameters to
                       //base class constructor
    // do something...
 }

Upvotes: 2

Related Questions