Abstract Classes

I have an inheritance hierarchy with 4 classes as illustrated below:

1
2
3
4
5
6
7
	    class A [Abstract]
	      ||
	      \/
	    class B [Abstract]
	 / /	   \ \
  class C1	      class C2 
 [Concrete]	     [Concrete]


I have declared 2 private variables inside class A.

Currently, if I create an object of class C1 or C2, I am passing the values needed to initialize the variables in A through the use of initialization lists.

For example, if I do new C1(2,6)
This will call the constructor in class B which in turn will call the constructor in class A, where finally the values 2,6 will be assigned to the two private variables declared in A. Example:

1
2
3
4
5
6
7
8
9
// Currently working:

C1::C1(int x, int y)
: B(x,y) // pass up to B
{}

B::B(int x, int y)
: A(x,y) // pass up to A
{}



If I try to pass the values directly from class C1 to class A I get an error. For example:

1
2
3
C1::C1(int x y)
: A(x,y) // Error
{}



My question is as follows:

Is there any way of doing this smarter/cleaner?

Because once I have a lot of variables that need to be set in class A, all of the subclass constructors will have huge initialization lists.

One thing that crossed my mind was to make the variables inside class A protected and then calling the setter methods for the class A variables inside the constructors of the concrete classes.

1
2
3
4
5
C1::C1(int x, int y)
{
   setVariable1(x); // sets var1 in class A
   setVariable2(y); // sets var2 in class A
}


Any further suggestions/comments?
Last edited on
> all of the subclass constructors will have huge initialization lists.
┬┐why is that a problem?
Well, lets say that I have 10 variables in class A that I need to assign values to. So when I create a C1 object, constructors will look as follows:

1
2
3
4
5
6
7
8

C1::C1(int a, int b, int c, int d, int e, int f, int g, int h, int i , int j )
: B(int a, int b, int c, int d, int e, int f, int g, int h, int i , int j ) // pass up to B
{}

B1::B1(int a, int b, int c, int d, int e, int f, int g, int h, int i , int j )
: A(int a, int b, int c, int d, int e, int f, int g, int h, int i , int j ) // pass up to A
{}


At some point in time I might also want to add and initialize variables in class B:

1
2
3
4
5
6
7
8
C1::C1(int x, int y, int a, int b, int c, int d, int e, int f, int g, int h, int i , int j )
: B(int x, int y, int a, int b, int c, int d, int e, int f, int g, int h, int i , int j ) // pass all values up to B
{}

B::B(int x, int y, int a, int b, int c, int d, int e, int f, int g, int h, int i , int j )
: m_X(x), m_Y(y), // init our 2 variables in B1
 A(int a, int b, int c, int d, int e, int f, int g, int h, int i , int j ) // pass rest up to A
{}


It seems like this will get very messy, very quickly. It would seem the use of actual set methods (declared protected) in class A or class B and called from the concrete class constructors (C1 or C2) would make this mess much clearer.

It would also mean that I wouldn't need to pass up so many different variables through all the various constructors.

Am I looking into this from a strange angle? I'm just hoping you can see my line of thinking here..
But you end with the same number of arguments.
The setters approach would require a default constructor in the base class. That's error-prone.

By the way, you are not `passing' the parameters in your examples.
Topic archived. No new replies allowed.