Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Inheritcance, references, constructors

Reply
Thread Tools

Inheritcance, references, constructors

 
 
Simon Elliott
Guest
Posts: n/a
 
      02-07-2005
A fairly standard polymorphic class which needs a reference to an
object:

class bar
{
int i1_;
};

class fooBase
{
public:
fooBase(bar& barRef):barRef_(barRef){}
virtual ~fooBase();
private:
bar& barRef_;
int i1_;
};

class fooDerived1ublic fooBase
{
public:
fooDerived1(bar& barRef):fooBase(barRef){}
private:
int i2_;
};

int main(int argc, char* argv[])
{
bar myBar;
fooBase* myFooBase = new fooDerived1(myBar);
delete myFooBase;
return 0;
}

Fine as far as it goes, but if you end up with several dozen or several
hundred fooDerivedN, maintenance becomes a bit tedious.

Let's say you wanted to add a reference to a bengist as well as a bar.
You have to change every single constructor of
fooDerived1..fooDerivedN. And if this is part of a large project with
several developers, you have to check out all these files meaning
no-one else can be working on them. Even if the change only takes 5
minutes this can be very disruptive.

Admittedly the compiler will let you know if you've missed one, but to
me it seems untidy to have to change constructors of lots of derived
classes. Is there a better way?

--
Simon Elliott http://www.ctsn.co.uk
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      02-08-2005
"Simon Elliott" <Simon at ctsn.co.uk> wrote...
>A fairly standard polymorphic class which needs a reference to an
> object:
>
> class bar
> {
> int i1_;
> };
>
> class fooBase
> {
> public:
> fooBase(bar& barRef):barRef_(barRef){}
> virtual ~fooBase();
> private:
> bar& barRef_;
> int i1_;


i1_ is left uninitialised. Did you intend to have it here?

> };
>
> class fooDerived1ublic fooBase
> {
> public:
> fooDerived1(bar& barRef):fooBase(barRef){}
> private:
> int i2_;
> };
>
> int main(int argc, char* argv[])
> {
> bar myBar;
> fooBase* myFooBase = new fooDerived1(myBar);
> delete myFooBase;
> return 0;
> }
>
> Fine as far as it goes, but if you end up with several dozen or several
> hundred fooDerivedN, maintenance becomes a bit tedious.
>
> Let's say you wanted to add a reference to a bengist as well as a bar.


I am sorry, what's a "bengist"?

> You have to change every single constructor of
> fooDerived1..fooDerivedN. And if this is part of a large project with
> several developers, you have to check out all these files meaning
> no-one else can be working on them. Even if the change only takes 5
> minutes this can be very disruptive.


Just like changing any other _interface_ of any base class from which
there are many derived classes. There should be no surprise.

> Admittedly the compiler will let you know if you've missed one, but to
> me it seems untidy to have to change constructors of lots of derived
> classes. Is there a better way?


No, there isn't. Changing interface is a maintenance nightmare. Just
be ready for it.

V


 
Reply With Quote
 
 
 
 
Simon Elliott
Guest
Posts: n/a
 
      02-08-2005
On 08/02/2005, Victor Bazarov wrote:
[snip]
> > class fooBase
> > {
> > public:
> > fooBase(bar& barRef):barRef_(barRef){}
> > virtual ~fooBase();
> > private:
> > bar& barRef_;
> > int i1_;

>
> i1_ is left uninitialised. Did you intend to have it here?


I included i1_ just to illustrate that fooBase will have other data
members and methods.

> > Fine as far as it goes, but if you end up with several dozen or
> > several hundred fooDerivedN, maintenance becomes a bit tedious.
> >
> > Let's say you wanted to add a reference to a bengist as well as a
> > bar.

>
> I am sorry, what's a "bengist"?


Just another arbitrary class.

> > You have to change every single constructor of
> > fooDerived1..fooDerivedN. And if this is part of a large project
> > with several developers, you have to check out all these files
> > meaning no-one else can be working on them. Even if the change only
> > takes 5 minutes this can be very disruptive.

>
> Just like changing any other interface of any base class from which
> there are many derived classes. There should be no surprise.


I'm not surprised, just wondered if there was a better way.

> > Admittedly the compiler will let you know if you've missed one, but
> > to me it seems untidy to have to change constructors of lots of
> > derived classes. Is there a better way?

>
> No, there isn't. Changing interface is a maintenance nightmare. Just
> be ready for it.


The only thing that occurs to me is to contain the references
somewhere. Something like this (untested):

struct fooBaseInits
{
fooBaseInits(bar& barRef, bengist& bengistRef):
barRef_(barRef),bengistRef_(bengistRef){}
bar& barRef_
bengist& bengistRef_;
};

class fooBase
{
public:
fooBase(fooBaseInits& inits):
barRef_(inits.barRef_),bengistRef_(inits.bengistRe f_){}
virtual ~fooBase();
private:
bar& barRef_;
bengist& bengistRef_;
};

class fooDerived1ublic fooBase
{
public:
fooDerived1(fooBaseInits& inits):fooBase(inits){}
private:
};

Then we can make as many changes as we want to fooBaseInits and the
rest of the code doesn't need to change. In fact for many of the
derived classes fooBaseInits can just be a forward declaration...

Any thoughts?

--
Simon Elliott http://www.ctsn.co.uk
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      02-08-2005
Simon Elliott wrote:
> [...]
> The only thing that occurs to me is to contain the references
> somewhere. Something like this (untested):
>
> struct fooBaseInits
> {
> fooBaseInits(bar& barRef, bengist& bengistRef):
> barRef_(barRef),bengistRef_(bengistRef){}
> bar& barRef_
> bengist& bengistRef_;
> };
>
> class fooBase
> {
> public:
> fooBase(fooBaseInits& inits):
> barRef_(inits.barRef_),bengistRef_(inits.bengistRe f_){}
> virtual ~fooBase();
> private:
> bar& barRef_;
> bengist& bengistRef_;
> };
>
> class fooDerived1ublic fooBase
> {
> public:
> fooDerived1(fooBaseInits& inits):fooBase(inits){}
> private:
> };
>
> Then we can make as many changes as we want to fooBaseInits and the
> rest of the code doesn't need to change. In fact for many of the
> derived classes fooBaseInits can just be a forward declaration...
>
> Any thoughts?
>


OK. Looks good. Now, how do you initialise the reference ('inits') that
is passed to the constructor of 'fooDerived1' and all other classes that
derive from 'fooBase'?

fooBaseInits inits = { some_bar, some_bengist };
fooDerived1 der(inits);

now, you need to add 'benbargist' to your initialisation sequence... And
you're back where you started, looking through all the code for the places
where 'inits' has to be changed.

V
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
reg constructors/copy constructors inheritance srp113 C++ 3 02-17-2009 04:01 PM
Is the possible to have all the public constructors of the publicbase class as the constructors of a derived class? Peng Yu C++ 5 09-19-2008 10:19 AM
compiler synthesized constructors/copy constructors/assignment operators Jess C++ 5 06-07-2007 11:09 AM
Copy constructors, de/constructors and reference counts Jeremy Smith C++ 2 08-02-2006 11:25 PM
Constructors that call other Constructors Dave Rudolf C++ 12 02-06-2004 03:26 PM



Advertisments