Overloading a base class' member - bad design?

Started by
1 comment, last by Shannon Barber 18 years, 11 months ago
Hello Is it bad design to override a base class' members? e.g.:
[source language="cpp"]
class CBaseClass
    {
    CAnotherBaseClass &somedata;

    CBaseClass(CAnotherBaseClass &r)
        : somedata(r)
        {
        }
    };

class CSubClass
    {
    CAnotherSubClass &somedata;

    CSubClass(CAnotherSubClass &r)
        : CBaseClass(r),
        somedata(r)
        {
        }
    };

class CAnotherBaseClass
    {
    // interesting stuff
    };

class CAnotherSubClass : public CAnotherBaseClass
    {
    };

So CBaseClass contains a reference to CAnotherBaseClass, which must be initialised on construction. CSubClass, a child of CBaseClass, overrides this member with a subclass of CAnotherBaseClass. CSubClass gets all the added features of CAnotherSubClass, without having to grab the member from CBaseClass and downcasting it. So - acceptable or !acceptable? I hope I've managed to get my point across here.
Advertisement
This is in my opinion very bad design. Members don't inherit in that way; a sub class inherits its members but declaring a member with the same name does not do what you intend (what I think you intend). What happens is a second variable is created on top of it. So adjusting values in the subclassed member in the subclass does not adjust the corresponding values of the member of its base class, if you see what I mean. An example does wonders:

#include <stdio.h>class COne{public:	int value;};class CTwo : public COne{};class CA{public:	COne m;};class CB : public CA{public:	CTwo m;};void main( void ){	CA a;	a.m.value = 1;	CB b;	b.m.value = 2;	CA* pA = &a;	CA* pB = &b;	printf( "pA->m.value = %d\n", pA->m.value );	printf( "pB->m.value = %d\n", pB->m.value );}


The last print statements print 1 and some undefined number, respectively. The second accesses the m member in the base class CA, which is uninitialised. I hope you see what I mean.

Forced initialization by making it a reference does make sure it is initialised, however it is still not what you'd expect naively when accessing the subclass base member.

Greetz,

Illco
It should be avoided. Why do the data members have the same name? Can the name of one them be improved (made more precise) to distinguish them?
The language allows it (well assuming C++, someone else will have to say for C# or Java but I think they would have to allow it), and there are ways to disambiguate access.

If the purpose is to over-take the behavior provided by the base member, then there ought to be member function to replace a pointer to the contained class. This is the 'template method' design pattern. iostreams & streambuf's are an example, streams contain a streambuf* that you can point to a customized streambuf.

PS stdio.h is deprecated for C++, use #include <cstdio> instead ;)
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement