C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problems with interface-like class and multiple inheritance
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Frank Buss
Guest





PostPosted: Fri Apr 16, 2004 3:58 pm    Post subject: Problems with interface-like class and multiple inheritance Reply with quote



I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?

BTW, this works, but it is useless for me:

((DerivedImpl*)b)->bar();

--
Frank Buß, [email]fb (AT) frank-buss (DOT) de[/email]
http://www.frank-buss.de, http://www.it4-systems.de

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Michael Karcher
Guest





PostPosted: Sat Apr 17, 2004 6:29 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote



Frank Buss <fb (AT) frank-buss (DOT) de> wrote:
Quote:
but this crashs, and the compiler doesn't even warn me Sad
This is because those old C casts are evil. It is interpreting your cast

like an reinperpret_cast, saying "compiler, I know you think this is
a pointer to base, but it really is a pointer to Interface". Which is isn't.
If you had written "static_cast<>" you would have got an compiler error.

Quote:
I assume the compiler doesn't know the right vtable, because of the
up-cast, without knowing the parallel class, because C++ doesn't have
runtime type information, if not compiled with RTTI, but how can I fix it
or perhaps there is a better solution?
For this to work, you need to use dynamic_cast<>, which makes use of RTTI.

But this also means you need a polymorphic base type, i.e. Base must contain
at least one virtual function (probably the destructor should be virtual if
you are using pointers to Base*). This works for me:


Quote:
BTW, this works, but it is useless for me:

#include <iostream>

class Base {
public:
virtual void f();
};

void Base::f() {}

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { cout << "testn"; }
};

int main(void)
{
Base * b = new DerivedImpl;

// Compiler error
// Interface* i = static_cast
Interface* i = dynamic_cast<Interface*>(b);
i->bar();
}

Michael Karcher

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
llewelly
Guest





PostPosted: Sat Apr 17, 2004 6:34 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote



Frank Buss <fb (AT) frank-buss (DOT) de> writes:

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;
[snip]


Interface* i = dynamic_cast<Interface*> (b) ;

The '(foo*) b' style casts are for backward compatiblity with C, not
for use with polymorphic objects.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Falk Tannhäuser
Guest





PostPosted: Sat Apr 17, 2004 6:36 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Frank Buss wrote:
Quote:
class Base {
public:
void foo() {}
};

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;
If you want the compiler to support you in determining whether or not

such conversions are well behaved, it is best to abandon the use of
C-style casts completely. The above line is equivalent to
Interface* i = reinterpret_cast<Interface*>(b);
which will not adjust the pointer as you want. If you desire the moral
equivalent of Java casts, you should use
Interface* i = dynamic_cast<Interface*>(b);
assert(i != 0);
// Be sure b really pointed to an object having dynamic type derived from Interface
or
Interface* i = &dynamic_cast<Interface&>(*b);
// Launches exception (like Java) if the cast failed
For this to work, class Base must be polymorphic! If you can modify its source,
add at least a virtual destructor.

Quote:
and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?
If RTTI doesn't work because Base is not polymorphic, the only solution I see is

Interface* i = static_cast<DerivedImpl*>(b);
which performs an unchecked downcast (yielding undefined behaviour if the dynamic
type of the object pointed to by b is not actually DerivedImpl or derived from it)
followed by the implicit (always well-formed) upcast to interface.

Falk

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Nikolai Borissov
Guest





PostPosted: Sat Apr 17, 2004 10:03 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Frank Buss wrote:

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me

Instead of keeping pointer to Base class you can keep a pointer to
interface through which you can access both Base and derived classes. The
idea is that interface class would provide both readdressing for Base
methods and additional methods for derived classes.

#include <iostream>

using namespace std;

// Base class
class Base
{ public:
void foo() {cout << "This is foo in Base" << 'n';}
int bar() {cout << "This is bar in Base" << 'n'; return -1;}
virtual void virt() = 0;
};

// Two generated derived classes (cannot be changed)
class Der1: public Base
{ void virt() {cout << "This is virt in Der1" << 'n';}
};
class Der2: public Base
{ void virt() {cout << "This is virt in Der2" << 'n';}
};

// Interface class
class Interface
{ public:
Interface(Base& b):_b(b){} // Reference to Base class is set here

// Base class interface
void foo() {_b.foo();}
int bar() {return _b.bar();}
void virt() {_b.virt();}

// Additional interface
virtual void I_foo() = 0;
virtual void I_bar() = 0;

private:
Base& _b; // reference to Base class
};

// Grouping classes that put together derived classes and interface
class Der1_Impl: public Der1, public Interface
{ public:
Der1_Impl():Interface(static_cast void I_foo() { cout << "This is I_foo in Der1" << 'n'; }
void I_bar() { cout << "This is I_bar in Der1" << 'n'; }
};
class Der2_Impl: public Der2, public Interface
{ public:
Der2_Impl():Interface(static_cast void I_foo() { cout << "This is I_foo in Der2" << 'n'; }
void I_bar() { cout << "This is I_bar in Der2" << 'n'; }
};

int main()
{
Interface* pI_1 = new Der1_Impl;
Interface* pI_2 = new Der2_Impl;
int rc;

// Call of Base methods
pI_1->foo();
rc = pI_1->bar();
cout << " return code from bar() = " << rc << 'n';
pI_1->virt();
// Call of additional interface methods
pI_1->I_foo();
pI_1->I_bar();

cout << 'n';

// Same for the second object
pI_2->foo();
rc = pI_2->bar();
cout << " return code from bar() = " << rc << 'n';
pI_2->virt();
pI_2->I_foo();
pI_2->I_bar();

return 0;
}


Nikolai Borissov



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Xenos
Guest





PostPosted: Sat Apr 17, 2004 10:06 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote


"Frank Buss" <fb (AT) frank-buss (DOT) de> wrote

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?

BTW, this works, but it is useless for me:

((DerivedImpl*)b)->bar();

I'm not sure, but I think you need to:

Interface* i = (DerivedImpl*) b;

instead of:

Interface* i = (Interface*) b;

To get the up-casting done correctly. I think, since the compile doesn't
"know" how to convert a Base directly to an Interface, you need to convert
Base to a DerivedImpl first (you need to go down then up). Also, you should
use static_cast or dynamic_cast instead of c-style casts.

DrX




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Serge N
Guest





PostPosted: Sat Apr 17, 2004 10:07 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

"Frank Buss" <fb (AT) frank-buss (DOT) de> wrote

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();
Then I think I can cast it back:
Interface* i = (Interface*) b;
and call the method:
i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?


If you used a dynamic_cast<Interface*>(b) instead of old-style C cast,
then compiler would complain (gcc-3.3.1 does) that your Base class is not
polymorphic -
it needs a virtual destructor. IMO, your code(as it is) may crash only when
you say "delete b;" (you'll try to delete derived class through the pointer
to the base class).

Bottom line: add virtual dtor to the base class and use dynamic_cast for
downcasting(sidecasting).

Sergey




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Sat Apr 17, 2004 10:32 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Frank Buss wrote:
Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator).

Perhaps you could post-process the code generator's output.

Quote:
Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad

You used a C-style cast, which means "I know what I'm doing so do the
conversion and shut up". This is why one should hardly ever use
C-style casts in C++.

Quote:
I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?

A C-style cast will never use RTTI. It is normally equivalent to some
combination of const_cast, static_cast and reinterpret_cast. In the
above case it is equivalent to a reinterpret_cast.

Quote:
BTW, this works, but it is useless for me:

((DerivedImpl*)b)->bar();

Yes, that should work and is equivalent to a static_cast.

Now, to perform a cross-cast via an unknown derived class, you need to
use dynamic_cast, which does make use of RTTI. If for some reason you
have to use an implementation lacking RTTI then you may have to
resort to using an associative array, thus:

class Interface
{
private:
typedef std::map<Base *, Interface *> BackMap;
static BackMap backMap_;
Base * const base_;

protected:
Interface(Base * base)
: base_(base)
{
backMap_[base] = this;
}
~Interface()
{
backMap_.erase(base_);
}

public:
// Emulation of dynamic_cast<Interface *>.
// This could be overloade for const pointers.
static Interface * fromBase(Base * base)
{
BackMap::const_iterator it = backMap_.find(base);
return (it == backMap_.end()) ? NULL : it->second;
}

...
};

Interface::BackMap Interface::backMap_;

class DerivedImpl : public Derived, public Interface
{
public:
// The use of "this" may provoke a warning, but it is safe.
DerivedImpl() : Derived(), Interface(this) {}
...
};

Note that the above is not thread safe. In a multithreaded program
you would need to protect all access to Interface::backMap_ with a
mutex.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Stephen C. Dewhurst
Guest





PostPosted: Sat Apr 17, 2004 10:48 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

On 16 Apr 2004 11:58:36 -0400, Frank Buss <fb (AT) frank-buss (DOT) de> wrote:

Quote:

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?

You're right; if you want to do this, you'll probalby need a dynamic
cast, as in

if( Interface *i = dynamic_cast<Interface *>(b) )
i->bar();

The dynamic_cast may or may not be a bad design choice. Another
option might be to use the External Polymorphism pattern. See
http://www.cs.wustl.edu/~cleeland/papers/External-Polymorphism/External-Polymorphism.html,
but be aware that the C++ template code is fairly old, and may need
some updating.

Steve
www.semantics.org

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
christopher diggins
Guest





PostPosted: Sun Apr 18, 2004 12:41 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

"Frank Buss" <fb (AT) frank-buss (DOT) de> wrote

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();

but this crashs, and the compiler doesn't even warn me Sad I assume the
compiler doesn't know the right vtable, because of the up-cast, without
knowing the parallel class, because C++ doesn't have runtime type
information, if not compiled with RTTI, but how can I fix it or perhaps
there is a better solution?

BTW, this works, but it is useless for me:

((DerivedImpl*)b)->bar();


Something that might work (if you only have a couple of interfaces) is to
write an interface class like IFuBar at
http://www.heron-language.com/cpp-iop-example.html and then you can rewrite
the example you gave us as:

--
class Base {
public:
void foo() {}
};

class Derived : public Base {
};

// Replace the following with the suggested IFubar style interface type
//class Interface {
//public:
//virtual void bar() = 0;
//};

class DerivedImpl : public Derived
// Remove the following: , public Interface
{
public:
void bar() { printf("testn"); }
};

Base* b = new DerivedImpl();

// changed from: Interface* i = (Interface*) b;
Interface i = b*;

// changed from: i->bar();
i.bar();

--

I hope what I am proposing makes sense and is helpful?

--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bill Weston
Guest





PostPosted: Sun Apr 18, 2004 12:42 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Frank Buss <fb (AT) frank-buss (DOT) de> wrote

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};

Now I can create the classes and perhaps storing it in containers, but I
can't cast it to the "Interface" to handle all objects the same:

Base* b = new DerivedImpl();

Why not create it as an Interface* ?

Interface* b = new DerivedImpl();

then b->bar() works fine, and
Interface* i = b;
i->bar();
work fine.

It can't be an old object, because you want to create it with
Dynamictype DerivedImpl. The other way around, if you want to try
passing an Interface* into code expecting a Base*, then you can use a
dynamic_cast, as others have detailed.

for dynamic_cast I believe you need the _INSTANCE_ in the round
brackets to have a virtual, whereas the _destination type_ in angle
brackets need not have.

So doing it this way round you are OK even if the Base type does not
have a virtual function

HTH,
BIll

Quote:

Then I think I can cast it back:

Interface* i = (Interface*) b;

and call the method:

i->bar();


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Chris Vine
Guest





PostPosted: Sun Apr 18, 2004 12:44 am    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Frank Buss wrote:

Quote:
I have a class "Base", from which I can derive many other classes, but I
can't change the "Base" class (it is from a foreign library) and I can't
change the fact that my other classes are derived from "Base" (they are
produced by a code generator). Now I want to implement common
functionality for all those classes, so I create a "Impl" class for each
generated class and derive it from another class, too, which I want to
use as something like an interface like in Java:

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

class Derived : public Base {
};

class Interface {
public:
virtual void bar() = 0;
};

class DerivedImpl : public Derived, public Interface {
public:
void bar() { printf("testn"); }
};


[snip]

You cannot cast directly from one base class to another base class of a
multiply inherited class as you propose, except with a dynamic cast
(requiring a virtual function in each base class).

The correct way of doing a static or C-style (that is, unchecked) cast in
these circumstances is to cast down the inheritance path and back up again,
viz:

Base* b = new DerivedImpl;
// explicit double cast
Interface* i = static_cast<Interface*>(static_cast<DerivedImpl*>(b));
// shorthand implicit double cast
Interface* j = static_cast<DerivedImpl*>(b);
i->bar();
j->bar();

The static_cast or C-style cast approach will not work if you are using
virtual (diamond-shaped) inheritance, but that is not what you are doing.

Chris.

--
To reply by e-mail, remove the "--nospam--" in the address

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bill Weston
Guest





PostPosted: Mon Apr 19, 2004 10:00 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Chris Vine <chris (AT) cvine--nospam-- (DOT) freeserve.co.uk> wrote

Quote:
Frank Buss wrote:


[snip]

You cannot cast directly from one base class to another base class of a
multiply inherited class as you propose, except with a dynamic cast
(requiring a virtual function in each base class).
^^^^

Only in the base class you set off from (the instance)...

#include <assert.h>

struct Foo { virtual ~Foo(){} };
struct Bar { };
struct Both : Foo, Bar { };

int main()
{
Foo* foo = new Both;
assert( dynamic_cast<Bar*>(foo) );
}

Bill Weston

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Frank Buss
Guest





PostPosted: Fri Apr 23, 2004 12:05 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

Ben Hutchings <do-not-spam-benh (AT) bwsint (DOT) com> wrote:

Quote:
Frank Buss wrote:
I have a class "Base", from which I can derive many other classes,
but I can't change the "Base" class (it is from a foreign library)
and I can't change the fact that my other classes are derived from
"Base" (they are produced by a code generator).

Perhaps you could post-process the code generator's output.

I use "uic" from Qt and I found a way to configure the base class to my
class, now I don't need multiple inheritance, but thanks for all the good
ideas.

--
Frank Buß, [email]fb (AT) frank-buss (DOT) de[/email]
http://www.frank-buss.de, http://www.it4-systems.de

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jerald Fijerald
Guest





PostPosted: Fri Apr 23, 2004 4:16 pm    Post subject: Re: Problems with interface-like class and multiple inherita Reply with quote

[email]Michael.Karcher (AT) writeme (DOT) com[/email] (Michael Karcher) wrote in message news:<c5p2fg$4aksg$1 (AT) uni-berlin (DOT) de>...
Quote:
Frank Buss <fb (AT) frank-buss (DOT) de> wrote:
but this crashs, and the compiler doesn't even warn me Sad
This is because those old C casts are evil. It is interpreting your cast
like an reinperpret_cast, saying "compiler, I know you think this is
a pointer to base, but it really is a pointer to Interface". Which is isn't.
If you had written "static_cast<>" you would have got an compiler error.

I assume the compiler doesn't know the right vtable, because of the
up-cast, without knowing the parallel class, because C++ doesn't have
runtime type information, if not compiled with RTTI, but how can I fix it
or perhaps there is a better solution?
For this to work, you need to use dynamic_cast<>, which makes use of RTTI.
But this also means you need a polymorphic base type, i.e. Base must contain
at least one virtual function (probably the destructor should be virtual if
you are using pointers to Base*). This works for me:


Well, C casts are not that dummy.
For example

float f = 3 / (float) 4;

Will not say "compiler, I know you think this is an integer but it
really is a float". If will convert 4 to 4.0.

So C casts may involve conversions.
In fact, I believe that if there are virtual tables in there, downcasting
with C casts is possible. At least that's what cfront did in the beginning.

Gerald
-------
too much man, you took too much. too much...

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.