inheritance ideas

M

Mike Frayn

Hi there. I'm wondering how to achieve a particular
functionality using virtual functions and class
inheritance... I don't know if its possible, but I figured
that I would give it a shot.

What I want is to have a base class with particular member
data and a virtual function that will be overloaded by the
inheriting class.

class CBaseClass
{
public:
virtual void OverLoadMe(void) {}
int DataFieldA;
};

In the inherited class, I will overload the function but I
would like to introduce new member data:

class CInheritedClassA : public CBaseClass
{
void OverLoadMe(void) { //happy now? }
float DataFieldB;
};

Now if I defined a variable like so:

CBaseClass* MyClass = new CInheritedClassA;

I would like to be able to access DataFieldB. Of course, I
can't, however the reason I'm looking for such functionality
is so that I can house a group of inheritedclassA-Z
instances in one list without having to have separate lists
for separate types.

So, while I do realize that this doesn't work, and
furthermore I also realize WHY this doesn't and shouldn't
work, I'm wondering if I can get around it without
COMPLETELY changing the design of what I have so far.

Thanks so much,
Mike
 
V

Victor Bazarov

Mike Frayn said:
Hi there. I'm wondering how to achieve a particular
functionality using virtual functions and class
inheritance... I don't know if its possible, but I figured
that I would give it a shot.

What I want is to have a base class with particular member
data and a virtual function that will be overloaded by the
inheriting class.

class CBaseClass
{
public:
virtual void OverLoadMe(void) {}
int DataFieldA;
};

In the inherited class, I will overload the function but I
would like to introduce new member data:

class CInheritedClassA : public CBaseClass
{
void OverLoadMe(void) { //happy now? }
float DataFieldB;
};

Now if I defined a variable like so:

CBaseClass* MyClass = new CInheritedClassA;

I would like to be able to access DataFieldB.

So, why not have a pure virtual function in CBaseClass that would
"access" your derived class data member? Why do you need to access
it, anyway?
Of course, I
can't, however the reason I'm looking for such functionality
is so that I can house a group of inheritedclassA-Z
instances in one list without having to have separate lists
for separate types.

So, the ability to access data members specific to derived classes
has really nothing to do with the reasons for which you created your
hierarchy, right? Then why are you trying to use the base class for
something it wasn't created to do?
So, while I do realize that this doesn't work, and
furthermore I also realize WHY this doesn't and shouldn't
work, I'm wondering if I can get around it without
COMPLETELY changing the design of what I have so far.

There is no reason to completely change the design. However, there
is a strong need for you to realise that WRT accessing data members
you have _no_design_ whatsoever, so there is nothing to change. If
you uncover your secret why you need that data (and public too), we
could probably suggest a couple of solutions.

V
 
T

Thomas Matthews

Mike said:
Hi there. I'm wondering how to achieve a particular
functionality using virtual functions and class
inheritance... I don't know if its possible, but I figured
that I would give it a shot. [snip]
class CBaseClass
{
public:
virtual void OverLoadMe(void) {}
int DataFieldA;
}; [snip]

class CInheritedClassA : public CBaseClass
{
void OverLoadMe(void) { //happy now? }
float DataFieldB;
}; [snip]


Thanks so much,
Mike

By the way, there is no reason to prefix all of
your classes with the letter 'C'. This is a
Microsoft naming convention.

See:
http://www.jelovic.com/articles/stupid_naming.htm


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
C

Cy Edmunds

[snip]
I would like to be able to access DataFieldB. Of course, I
can't, however the reason I'm looking for such functionality
is so that I can house a group of inheritedclassA-Z
instances in one list without having to have separate lists
for separate types.

You might have a look at boost::any at

www.boost.org
 
V

Victor Bazarov

Thomas Matthews said:
[...]
By the way, there is no reason to prefix all of
your classes with the letter 'C'. This is a
Microsoft naming convention.

Actually, it's not just Microsoft. You'd be surprised how many other
software companies have their own naming conventions that look similar
and must seem unnecessary. Of course, Microsoft gets bashed because
they published theirs...

V
 
D

Daniel T.

Mike Frayn said:
Hi there. I'm wondering how to achieve a particular
functionality using virtual functions and class
inheritance... I don't know if its possible, but I figured
that I would give it a shot.

What I want is to have a base class with particular member
data and a virtual function that will be overloaded by the
inheriting class.

class CBaseClass
{
public:
virtual void OverLoadMe(void) {}
int DataFieldA;
};

In the inherited class, I will overload the function but I
would like to introduce new member data:

class CInheritedClassA : public CBaseClass
{
void OverLoadMe(void) { //happy now? }
float DataFieldB;
};

Now if I defined a variable like so:

CBaseClass* MyClass = new CInheritedClassA;

I would like to be able to access DataFieldB. Of course, I
can't, however the reason I'm looking for such functionality
is so that I can house a group of inheritedclassA-Z
instances in one list without having to have separate lists
for separate types.

So, while I do realize that this doesn't work, and
furthermore I also realize WHY this doesn't and shouldn't
work, I'm wondering if I can get around it without
COMPLETELY changing the design of what I have so far.

void dealWithDataFieldB( CBaseClass* bc ) {
CInheritedClassA* ic = dynamic_cast< CInheritedClassA >( bc );
assert( ic );
ic->DataFieldB = 5;
}

Note the assert. I would only recommend using this in cases where you
know that the object in question is going to be a CInheritedClassA
object *every* time this piece of code is run. IMHO of course.
 
J

John Harrison

Mike Frayn said:
Hi there. I'm wondering how to achieve a particular
functionality using virtual functions and class
inheritance... I don't know if its possible, but I figured
that I would give it a shot.

What I want is to have a base class with particular member
data and a virtual function that will be overloaded by the
inheriting class.

class CBaseClass
{
public:
virtual void OverLoadMe(void) {}
int DataFieldA;
};

In the inherited class, I will overload the function but I
would like to introduce new member data:

class CInheritedClassA : public CBaseClass
{
void OverLoadMe(void) { //happy now? }
float DataFieldB;
};

Now if I defined a variable like so:

CBaseClass* MyClass = new CInheritedClassA;

I would like to be able to access DataFieldB. Of course, I
can't, however the reason I'm looking for such functionality
is so that I can house a group of inheritedclassA-Z
instances in one list without having to have separate lists
for separate types.

So, while I do realize that this doesn't work, and
furthermore I also realize WHY this doesn't and shouldn't
work, I'm wondering if I can get around it without
COMPLETELY changing the design of what I have so far.

Thanks so much,
Mike

Just define virtual functions which access the data members you want.

You shouldn't be defining public data anyway, that's rule 1 of OO design.

john
 
M

Mike Frayn

By the way, there is no reason to prefix all of
your classes with the letter 'C'. This is a
Microsoft naming convention.

I disagree, I believe there is a reason and that's why I use
it.

Mike
 
M

Mike Frayn

Aha! Thanks Dan!

Mike

Daniel T. said:
void dealWithDataFieldB( CBaseClass* bc ) {
CInheritedClassA* ic = dynamic_cast< CInheritedClassA
( bc );
assert( ic );
ic->DataFieldB = 5;
}

Note the assert. I would only recommend using this in cases where you
know that the object in question is going to be a CInheritedClassA
object *every* time this piece of code is run. IMHO of
course.
 
M

Mike Frayn

Just define virtual functions which access the data
members you want.

Hmmm, but then I may as well have placed all the data
members in the base class. No? Seems to me that they'd
both look equally unattractive.
You shouldn't be defining public data anyway, that's rule
1 of OO design.

I should have figured I'd receive grief for that. It was
irrelevant to my example so I didn't bother.

Mike
 
J

John Harrison

Mike Frayn said:
members you want.

Hmmm, but then I may as well have placed all the data
members in the base class. No? Seems to me that they'd
both look equally unattractive.

If all derived classes (now and in the future) share the data members, then
put them into the base class. If they don't then don't. I don't really see
the problem.

There's nothing to stop you putting an error catching virtual method in the
base class.

class Base
{
public:
virtual int getA() const { throw "no A exists in Base"; }
};

class Derived : public Base
{
public:
virtual int getA() const { return a; }
private:
int a;
};

john
 
M

Mike Frayn

Okay John, you seem to be approaching this as if I already
understand what the right answer is. What's the problem?
The problem is that I don't understand :)

Uhm, my point was simply that if I'm going to add a virtual
function for every data member that is added in a derived
class, then I'll have a bunch of virtual functions in the
base class, some of which get used in derivations from it
and some that don't. That seems to be the same, to me, as
simply defining all the member variables in the base class
and then only using some of them in each particular derived
class.

Mike
 
J

John Harrison

Mike Frayn said:
Okay John, you seem to be approaching this as if I already
understand what the right answer is. What's the problem?
The problem is that I don't understand :)

Uhm, my point was simply that if I'm going to add a virtual
function for every data member that is added in a derived
class, then I'll have a bunch of virtual functions in the
base class, some of which get used in derivations from it
and some that don't. That seems to be the same, to me, as
simply defining all the member variables in the base class
and then only using some of them in each particular derived
class.

Mike

OK well now I understand. Two advantages of using virtual functions are

1) You get error checking, if a derived class tries to access a variable it
doesn't have then the base class virtual function can detect this (as in my
last post)
2) You save space, only the derived classes that have member variables will
actually have them, instead of all derived classes having them by virtue of
there being in the base class.

I think your approach to the design of a inheritance tree is a little
backward. You say 'if I'm going to add a virtual for every data member that
is added in a derived class' but really when you are designing this you
should be thinking of *all* the functionality you need in the base class.
Derived classes do not add functionality to this, they implement the base
class functionality in different specialised ways. At least that what the
books say, real world is sometimes a little more complex.

john
 
D

Daniel T.

Mike Frayn said:
members you want.

Hmmm, but then I may as well have placed all the data
members in the base class. No? Seems to me that they'd
both look equally unattractive.

Putting *any* member-data in a base class is unattractive AFAIC.
1 of OO design.

I should have figured I'd receive grief for that. It was
irrelevant to my example so I didn't bother.

Yea, I figured you were just trying to simplify the example. In the
future use member functions instead:

class Base {
public:
void fn1();
};

class Derived: public Base {
public:
void fn2();
};

void problem( Base& b ) {
// note: the same problem exists... how do we
// access fn2 when all we have a a Base&?
dynamic_cast<Derived>(b).fn2();
// The above will throw if b isn't a a Derived object.
}

The above is poor programming practice, but it does solve the problem
you are having.

It is poor programming practice because the code that calls problem()
(or the programmer writing that code) must *know* that the object is
actually a Derived object and not some other class derived from Base (or
a Base object itself,) yet that knowledge won't be exposed in the code,
because a Base pointer/reference is being thrown around, instead of a
Derived pointer/reference.
 
D

Daniel T.

Mike Frayn said:
I disagree, I believe there is a reason and that's why I use
it.

Good for you! It's good to know why we do things. I think you would
agree though that there is no 'language' reason to use the 'C' prefix.
Personally, I think the prefix adds unnecessary complexity to the bit of
code presented, even if it is useful to you in your project as a whole.
Just MHO of course.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top