Reputation: 405
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
the procedure I use to compute the number of vertices is complicated.(many lines of code rather than a+b
)
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
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
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
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
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