multiple base objects, real-life scenario.

P

Paul

In real life situation, do we ever come across a situation where we
would need two base objects in an object.
A snippet is worth 1000 words :) so...

class Base
{
};
class Derived1:public Base
{
};
class Derived2: public Base
{
};
class Dervied12:public Derived1, public Derived2
{
//two objects of Base
};
//typical, just no virtual derivation of Base
Just to set the point right, I know we can remove one Base by using
virtual, but that's exactly not the goal here, do we have case where
we need two Base objects, can we compare it with any real life
situation.
Is amphibian comes any way close to this???
your inputs are appreciated.

thanks,
-Paul.
 
T

Thomas Matthews

Paul said:
In real life situation, do we ever come across a situation where we
would need two base objects in an object.
A snippet is worth 1000 words :) so...

class Base
{
};
class Derived1:public Base
{
};
class Derived2: public Base
{
};
class Dervied12:public Derived1, public Derived2
{
//two objects of Base
};
//typical, just no virtual derivation of Base
Just to set the point right, I know we can remove one Base by using
virtual, but that's exactly not the goal here, do we have case where
we need two Base objects, can we compare it with any real life
situation.
Is amphibian comes any way close to this???
your inputs are appreciated.

thanks,
-Paul.

You are describing the Diamond Inheritance pattern.
This is described in the C++ FAQ. Searching the FAQ
before posting is a very good thing.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8

Try this one:
class Field {};
class Record {};

class Look_Up_Field
: public Field,
public Record
{
};

Given a table of records. A record is composed of one or
more fields.

Let there be a Look-up field. The Look-up Field is a _proxy_
for one or more data fields. The Look-up Field can be treated
as a single field in a record or as a record in another table.
Thus it has the behavior of both a single field and as a
record.


--
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.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
P

Paul

In real life situation, do we ever come across a situation where we
would need two base objects in an object.
A snippet is worth 1000 words :) so...

class Base
{
};
class Derived1:public Base
{
};
class Derived2: public Base
{
};
class Dervied12:public Derived1, public Derived2
{
//two objects of Base
};
//typical, just no virtual derivation of Base
Just to set the point right, I know we can remove one Base by using
virtual, but that's exactly not the goal here, do we have case where
we need two Base objects, can we compare it with any real life
situation.
Is amphibian comes any way close to this???
your inputs are appreciated.

thanks,
-Paul.
Yes multiple inheritance is common.
If you are familiar with java you will know about implementing
intefaces.
In C++ Interfaces are called ADT's (abstract data types).
The best example I can think of is the platform specific ATL and COM
where multiple Interfaces are used.
Consider this:
/*Interfaces*/
class Imechanical{
};
class Ibiological{
};
class ILandThing{
};
class ISeaThing{
};

/*classes which use Interfaces*/
class Truck: Imechanical, ILandThing{
};
class AmphibiousTruck: Imechanical,ILandThing, ISeaThing{
};
class Salmon: Ibiological, ISeaThing{
};
class LungFish: Ibiological, ILandThing, ISeaThing{
};

perhaps the Imechanical interface has a needs_oil property and the
Ibiological has a bool property needs_to_reproduce :)
then these methods are inherited by implementing the appropriate
Inteface.

As I said this is a major concept in Java and also in C# but in C++ it
seems only to be common in specialized areas.

I think it demands a different type of understanding from the basic
C++, a bit like templates, but that's only my perception. I'm sure we
all have different angles of looking at different types of code
solutions. For example:
How do you see this?
class Base{};
class Derived:Base{};
Base* pb = new Derived;
static_cast<Dervied* >(pb);

Do you think of it as casting down or casting up ?

I naturally think of it as casting up as it's being cast to a
superior, or more complicated, object. But I think the general C++
programming community would call it casting down. I'm not 100% sure on
this it's just a book I am reading uses this term in this way. It'd be
appreciated if you could clear this up.

HTH & HTIC
Paul.
 
P

Paul

Yes multiple inheritance is common.
If you are familiar with java you will know about implementing
intefaces.
In C++ Interfaces are called ADT's (abstract data types).
The best example I can think of is the platform specific ATL and COM
where multiple Interfaces are used.
Consider this:
/*Interfaces*/
class Imechanical{
};
class Ibiological{
};
class ILandThing{
};
class ISeaThing{
};

/*classes which use Interfaces*/
class Truck: Imechanical, ILandThing{
};
class AmphibiousTruck: Imechanical,ILandThing, ISeaThing{
};
class Salmon: Ibiological, ISeaThing{
};
class LungFish: Ibiological, ILandThing, ISeaThing{
};

perhaps the Imechanical interface has a needs_oil property and the
Ibiological has a bool property needs_to_reproduce :)
then these methods are inherited by implementing the appropriate
Inteface.

As I said this is a major concept in Java and also in C# but in C++ it
seems only to be common in specialized areas.

I think it demands a different type of understanding from the basic
C++, a bit like templates, but that's only my perception. I'm sure we
all have different angles of looking at different types of code
solutions. For example:
How do you see this?
class Base{};
class Derived:Base{};
Base* pb = new Derived;
static_cast<Dervied* >(pb);

Do you think of it as casting down or casting up ?

I naturally think of it as casting up as it's being cast to a
superior, or more complicated, object. But I think the general C++
programming community would call it casting down. I'm not 100% sure on
this it's just a book I am reading uses this term in this way. It'd be
appreciated if you could clear this up.

HTH & HTIC
Paul.

Paul thanks for your inputs. I am afraid you didn't get the problem
right or I failed to explain (-: Nowhere in your derived classed two
same base objects appear. Your derived are providing/comprising more
than one set of functionalities.
Coming to your up/down-casting, it depends how we define up / down. In
a family tree father comes up and children come down, in an
orginization tree Manager comes up and employee comes down.
I take it this way with which you may differ...

Base
^
|
Derived

Base* b = new Derived; is up-casting, just thumb rule, I am going up
the tree by this. Well you may turn the image upside down and see it
;-)
Which we way do you prefer to see it. (Schrodinger's Cat is dead or
alive?)

-Paul
 
P

Paul

Thomas Matthews said:
You are describing the Diamond Inheritance pattern.
This is described in the C++ FAQ. Searching the FAQ
before posting is a very good thing.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8
but I am not refering to Diamond Inheritance, I am just looking for a
scenario where we would need two base objects in a derived class. I am
afraid you got it wrong.
Try this one:
class Field {};
class Record {};

class Look_Up_Field
: public Field,
public Record
{
};

Given a table of records. A record is composed of one or ^^^^^^^^
more fields.

it should be composition and not inheritance.
clas Record
{
Collection<Field> _fc;
};
and in your example Look_Up_Field, there are no base copies and is not
an example of Diamond pattern, since there is no common base, its just
half of that diamond. :)
Let there be a Look-up field. The Look-up Field is a _proxy_
for one or more data fields. The Look-up Field can be treated
as a single field in a record or as a record in another table.
Thus it has the behavior of both a single field and as a
record.


--
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.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book

any how thanks for your time.

-Paul.
 
P

Paul

snip
Consider this:
/*Interfaces*/
class Imechanical{
};
class Ibiological{
};
class ILandThing{
};
class ISeaThing{
};
snip

Sorry, image all these interfaces themselves derive from a more common
Interface such as IMovable.
I should then meet the requirements.

Paul.
 
T

Thomas Matthews

Paul said:
but I am not refering to Diamond Inheritance, I am just looking for a
scenario where we would need two base objects in a derived class. I am
afraid you got it wrong.
Your example _is_ diamond inheritance:
Base
/ \
Derived1 Derived2
\ /
Derived12
Hmm, if smells like a diamond pattern...
Perhaps you should say what you mean and mean what you say.

it should be composition and not inheritance.
If you look very close, I did not specify any inheritance
for class Record. I was giving you a real world example
which matched your query.

Your query was for examples of inheriting from multiple
base classes. That is what I presented.
Perhaps you should say what you mean and mean what you say.
clas Record
class Record
^
{
Collection<Field> _fc;
};
Nope, that won't work. In databases, fields can be of more than
one type, such as strings, integers and floating point.

The _implementation_ would be:
class Record
{
Collection<Field *> _fc;
};
With pointers, one can use polymorphism and not care about the
details of each field.
and in your example Look_Up_Field, there are no base copies and is not
an example of Diamond pattern, since there is no common base, its just
half of that diamond. :)
Hmm, look at _your_ original post. Review mine.
I _never_ stated that Look_Up_Field was a diamond pattern.
I _never_ stated that there were base copies, just multiple inheritance.
You never stated anything about copies of base classes.
I stated that your example that you provided was an example of the
Diamond Inheritance pattern.

--
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.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
V

Victor Bazarov

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The key words here are "would need".

While this doesn't look like a question, it is a question. It begins
with "do we have case". So, the question was "Do we ever, in real life,
have a case where we'd need two Base objects in one 'Derved12'?
Hmm, look at _your_ original post. Review mine.

I am puzzled why you cared to reply. You apparently didn't understand
the question.
I _never_ stated that Look_Up_Field was a diamond pattern.
I _never_ stated that there were base copies, just multiple inheritance.
You never stated anything about copies of base classes.

Yes, he did.
I stated that your example that you provided was an example of the
Diamond Inheritance pattern.

Not necessarily. For all we know, 'Base' subobjects of 'Derived1' and
'Derived2' are not the same. You cannot claim diamond inheritance when
there _can_ be a difference between 'Base' subobjects in the same class.

It is not possible in C++, but essentially, the example boils down to

struct Derived : Base, Base {
Derived() : Base(some_argument_1), Base(some_argument_2) {}
};

The only way to simulate that in C++ is by using either containment:

struct Derived {
Base b1, b2;
Derived : b1(some_argument_1), b2(some_argument_2) {}
};

or intermediate derived classes:

struct D1 : Base {
D1() : Base(some_argument_1) {}
};

struct D2 : Base {
D2() : Base(some_argument_2) {}
};

struct Derived : D1, D2 {};

The question of this thread is, "do we ever need that in real life?"

The question _isn't_ "Is that a diamond inheritance?"

The question _isn't_ "How to prevent multiple base class objects?"

Victor
 
K

Karl Heinz Buchegger

Thomas said:
Your example _is_ diamond inheritance:
Base
/ \
Derived1 Derived2
\ /
Derived12
Hmm, if smells like a diamond pattern...
Perhaps you should say what you mean and mean what you say.

What Paul means is:
Have you ever encountered a situation where you *don't* want
a diamond pattern. i.E where

Base Base
| |
Derived1 Derived2
\ /
Derived3

is the correct solution.

(Paul correct me if I got it wrong)

For me the answer is: No. I never have encountered
such a situation.
 
P

Paul

Victor Bazarov said:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The key words here are "would need".


While this doesn't look like a question, it is a question. It begins
with "do we have case". So, the question was "Do we ever, in real life,
have a case where we'd need two Base objects in one 'Derved12'?


I am puzzled why you cared to reply. You apparently didn't understand
the question.


Yes, he did.


Not necessarily. For all we know, 'Base' subobjects of 'Derived1' and
'Derived2' are not the same. You cannot claim diamond inheritance when
there _can_ be a difference between 'Base' subobjects in the same class.

It is not possible in C++, but essentially, the example boils down to

struct Derived : Base, Base {
Derived() : Base(some_argument_1), Base(some_argument_2) {}
};

The only way to simulate that in C++ is by using either containment:

struct Derived {
Base b1, b2;
Derived : b1(some_argument_1), b2(some_argument_2) {}
};

or intermediate derived classes:

struct D1 : Base {
D1() : Base(some_argument_1) {}
};

struct D2 : Base {
D2() : Base(some_argument_2) {}
};

struct Derived : D1, D2 {};

The question of this thread is, "do we ever need that in real life?"

The question _isn't_ "Is that a diamond inheritance?"

The question _isn't_ "How to prevent multiple base class objects?"

Victor

We could also use templates
Example:-

template<class T>
class Base{};

template<class T>
class Derived1:Base<T>{};

template<class T>
class Derived2:Base<T>{};

template<class T1, class T2>
class MoreDerived: Derived1<T1>, Derived2<T2>{};


then instantiate like this:-
MoreDerived<int,double> md;


This combined with derived classes' different implementation of pure
virtual functions is what I was trying to explain in my other
wafflings abour ATL etc.

HTH
Paul.
 

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
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top