I've noticed that when constructing a subclass, the base class get's
it's contructors called.
Is there some way to avoid this? The base class has one variable, which
gets initialised to 0.
The subclass's constructor sets this variable to a real value.
So first the variable is set to 0, the variable is never used before it
once again gets set to a real value. It's a waste. Any ideas anyone?
The solution is to design the base class for inheritance. When you are
designing a class to be used as a base class, you have to create
intelligent constructors that will be useful for the derived class
authors.
That way you don't have to assign to a member variable after the base
class constructor runs: you invoke the right base class constructor
where you can pass down the value that will go into that variable.
class Base {
protected:
int x, y;
Base(int xv, int yv);
public:
Base();
};
In this class, there is a public default constructor for the world to
use. It initializes the protected members x and y with some default
values. The member variables are not accessible from the outside.
But, a derived class has access to x and y. This is deliberately so.
And for that reason, a constructor is provided which initializes x and
y. The derived class authors might want different initial values for
these variables, and not the defaults that are set up in the default
constructor used by the rest of the world, so in the derived class:
class Derived : public Base {
public:
// initialize members x and y with 40 and 50
Derived() : Base(40, 50) { /* ... */ }
};
You call the base class constructor from the derived one using the
above syntax in the initializer list.
In general, you have to be quite flexible about initialization. If your
initialization is too encapsulated, life is difficult for derived class
writers: they have to allow your default initializations to occur, and
then mutate the object in various ways. Sometimes, those extra steps
can be quite expensive.
Imagine a GUI object which sets up a whole ton of defaults by calling
the window system. The derived object then has to make a whole ton of
more calls to override those defaults.
E.g. suppose a text widget object creates a default font. It calls the
GUI framework to search for the font by name, size, boldness, and other
attributes. It constructs the font object and retains the handle, etc.
Then, the derived class wants a different default font. Oops! So we
deallocate that one, and do it all over again ... It could all be
avoided by taking the font parameters through the constructor, or
providing two-step initialization.