Adie said:
Sadly the coverage of standard C++ was poor, three modules (classes) in
total - the first gave us; void main() for which I promptly wrapped on
the knuckles for using on Usenet, the second offered an intro into GUI
toolkits with X, Athena and Qt whilst the third concentrated on using
Borland CPP Builder libraries/GUI with some UML/Patterns stuff thrown in
for good measure. I suppose they're worried that most people would become
bored with three straight C++ modules, disadvantage being that we didn't
get a good coverage of what are considered the basics.
Unfortunately this seems to be a common trend. The perception that C++
is "too difficult" compared to languages like Java and Visual Basic has
really damaged the educational possibilities.
Oh well, there's always books and Usenet, I'll get there in the end
As a self-taught programmer I've picked up an aweful lot of useful stuff
online :>
The downside is that I don't have a piece of paper to tell prospective
employers that I'm able to do what I've *been* doing for the past 7
years. Makes it rather difficult to get work, even though they claim
we've got a shortage of C++ programmers over here at the moment.
Doesn't that go against the grain of keeping Base classes as lightweight
as possible?
Code-wise, not really. Your base class doesn't actually have to
implement *any* of those interfaces if you really want it to stay light.
All of the functionality can be implemented down the inheritence tree.
That said, this is a fairly common structure in some areas:
class base_object
{
public:
base_object();
virtual ~base_object();
// some interfaces common to all derived
//...
};
class derived1a : public base_object
{
public:
derived1();
virtual ~derived1();
// common interfaces implemented in this class
//...
// new interfaces implemented for this branch
//...
};
class derived1b : public base_object
{
// like derived1a, but with different new interfaces
};
etc. This allows you to store all of your derived objects in a
base_object pointer, or vector of pointers, or whatever. Each branch
then has to be identified at its branch point using dynamic_cast<>().
So if I have a vector full of base_object*s and I need an interface
that's only provided by objects descended from derived1b, I can filter
the vector with dynamic_cast<>().
It has its uses. It can simplify certain aspects of your programs, but
overuse can make your code that much more difficult to read. Usually
it's preferable to have a more complete interface in the base and
provide implementation details in the descendants.