Re: Inheritance: Implementing pure virtual functions by inheriting
from an object providing an implementation
* Jaco Naude:
Hi again,
I've tried the new implementation but casting becomes really confusing
in this implementation.
Casting is generally to be avoided. :)
Let me give some details on my implementation.
The ManageMe class from my first post looks like this:
class ManageMe: public GCF::AbstractComponent, public ManagableObject,
virtual public IToolbox, virtual public IData
where each of the parent classes are defined as follows (Using Qt,
hence the reason for the QObject class below):
Hm. I only tried installing Qt once, for Windows. Had to try to install three
times to get it working, and the backspace key didn't work in the installation
dialog; one wonders how on Earth they managed to make that not work. I was very
tempted to walk up the street to Trolltech and tell them how uncute their
product was, and even more tempted when I tried to uninstall...
class AbstractComponent : public QObject -- This is a singleton
Double hm. Singletons are generally problematic. When you inherit from a
singleton class, if that's what you're doing, how do you ensure the singleton
will be of your class?
class ManagableObject : virtual public IManagable
class IData : virtual public IContainer
class IToolbox : virtual public IContainer
class IManagable : virtual public IContainer
No AbstractComponent here, AFAICS.
The IContainer class is a container class defined as follows:
class IContainer
{
public:
virtual QObject* containerObject() = 0;
};
From the name it sames that an IContainer /contains/ a QObject.
In the ManageMe class the IContainer interface is implemented as
follows:
QObject* ManageMe ::containerObject()
{
return this;
}
If this compiles then it seems ManageMe inherits from QObject.
Ok, that's my class hierarchy explained. Now I'm trying to cast to
IManagable* when I have a QObject pointer.
Well, above I see no inheritance relationship between IManagable and QObject. On
the contrary, IManagable implements the IContainer interface. Which indicates
that an IManagable is an interface on an object that /contains/ a QObject.
The way I try to do it is shown below and causes a program crash:
if (qobject_ptr) {
ManagableObject* tmp_ref = dynamic_cast<ManagableObject*>
(qobject_ptr);
if (tmp_ref) {
IManagable* managable_ptr = dynamic_cast<IManagable*>
(tmp_ref);
if (managable_ptr) {
// Access managable_ptr's contents here causes crash.
}
}
}
I've tried various variations of the above without anything working.
How is it possible to do this? Is it possible at all?
Try to reproduce the problem in a *minimal* program.
That often helps.
But also think about inheritance versus containment, and think about that
singleton thing -- could be a problem.
Also, it seems you have a needless proliferation of interface classes.
Interface abstraction is good when it helps you avoid doing wrong things or
helps avoid too close coupling, but it's bad when any realistic concrete class
has to implement and expose umpteen interfaces. Then the abstraction tool that
should simplify things instead complicates things. That happened a lot with COM;
if you look up the standard joke "progression of a programmer" starting with
hello, world in basic, and so on, the final horrifying mess is COM-based code.
Cheers & hth.,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!