Virtual inheritance and interfaces

M

Maarten Kronenburg

"Rolf Magnus" wrote in message
However, it is needed for B::f1().
Yes, but the runtime type version (via vtable) is only called when calling
it like x.f1() or p->f1(). But calling x.B::f1() or p->B::f1() I think means
calling the class B version, no matter what the runtime type of the object
(see [class.virtual]).
That offset can be determined at compile time.
Yes that seems me to be correct. The data members are never virtual in the
virtual function sense.
However, that usually resolves to three levels of pointer indirections.
When I read:
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.4
then I think it is a little less, more like 2 extra indirections
(fetch,fetch,call).
It seems to me that when using two vtable pointers in one object, then the
runtime type of the object can change. As mentioned this is also more or
less suggested by Item 24 in More Effective C++, the picture on page 120.
But in the standard in [class.virtual] item 7: "The interpretation of the
call of a virtual function depends on the type of the object for which it is
called (the dynamic type), whereas...". In my opinion, when using two vtable
pointers in one object, the dynamic type is no longer unique for an object,
but can change, which I think is not mentioned in the standard.
If I say:
Base *p = new Derived3();
no matter how many times the object is (multiply) derived, I expect that
object to remain of the same run-time type (Derived3) during its lifetime.
The compile-time type of the pointer can of course be changed with casts,
but as mentioned this should as far as I know not change the vtable pointer,
that is the run-time type. This is why I think that an object can have only
one vtable pointer.
It explains how vtables are handled by GCCs C++ front end, especially for
multiple and virtual inheritance. That should explain it.


The dynamic_cast doesn't have to return the same address your provided. It
might add an offset.
See my comment above.
Regards, Maarten.
 
G

Grizlyk

Dave said:
Since C++ is missing the "interface" concept present in Java, I've been
using
the following pattern to simulate its behavior:


Abstract class is what you need. C++ is compiling language, so you must
create object by any, but defined way. If you write "class Implementation
implement Itf0" how object of Implementation should be created?
class Interface0
{
public:
virtual void fn0() = 0;

make virtual dtor

virtual ~Interface0(){}
};

class Interface1
{
public:
virtual void fn1() = 0;


make virtual dtor

virtual ~Interface1(){}
};

class Implementation0: public virtual Interface0, // note "public virtual"
public virtual Interface1

You can refuse from virtual base classes. Write like this

class Implementation0: public Interface0,
public Interface1
{
public:
virtual void fn0(); // implementation

you no need to repeat virtual here

{
public:
void fn0(); // implementation
void fn1(); // implementation
/* ... */

make virtual dtor

virtual ~Implementation0(){}
};

Using virtual inheritance also allows me to create mixin classes. For
example:


class DefaultInterface0Implementation : public virtual Interface0

Here the same - avoid virtual base

class DefaultInterface0Implementation : public Interface0
{
public:
virtual void fn0(); // implementation

You no need to repeat virtual here

{
public:
void fn0(); // implementation
};
class Implementation1: public virtual Interface0,
public virtual Interface1,
private DefaultInterface0Implementation // mixin
{

You are trying to inherit implementation here: "private
DefaultInterface0Implementation". In most cases is better to do composition
instead

template<class Imp=DefaultInterface0Implementation>
class Implementation1: public Interface0,
public Interface1
{
protected:
Imp imp;

public:
void fn0(){imp->fn0();}
void fn1(){imp->fn1();}

public:
virtual ~Implementation0(){}
};
Does anyone have a better set of rules that I can consider using?

Try learn "desing patterns" if you have learnt about non-OO programming,
abstract data types and three bases of OOP (polimorphism, inheritance,
encapsulation) and its goals.
 
D

Dave Rahardja

Try learn "desing patterns" if you have learnt about non-OO programming,
abstract data types and three bases of OOP (polimorphism, inheritance,
encapsulation) and its goals.

Please read the previous posts in this thread before adding your comments.
Explanations on why I chose to use virtual inheritance, etc. are present in
the original posts.

-dr
 
G

Grizlyk

Dave said:
Please read the previous posts in this thread before adding your comments.
Explanations on why I chose to use virtual inheritance, etc. are present
in
the original posts.

I have read it but do not find any objections to my advice. If you want to
increase the quality of your classes and apply to your programm OO design,
you must not to see on classes from coding side.

"Desing patterns" can help you to build classes and you will see, why
inheritance of implementation from your example is not a best decision in
the case. And in oder to understand design pattern you need to understand
more simple things, as I enumerated.

Once day I already have written about it, serach group
For 5, they say, there is "easy to understand" book:
A. Shalloway, J. Trott
Design Pattern Explained
Addison-Wesley, 2002
www.netobjectives.com/dpexplained

And what about example of composition? Why not?
 

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

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,191
Latest member
BuyKetoBeez

Latest Threads

Top