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 

Implementierung in einem Vererbungsweg

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Helge Kruse
Guest





PostPosted: Thu Dec 18, 2003 8:10 pm    Post subject: Implementierung in einem Vererbungsweg Reply with quote



Hallo,

ich möchte mit Vererbung eine Gruppe von Interfacen implementieren, die alle
von einem gemeinsamen Interface abgeleitet sind. Ich habe hierfür keine
intelligente Lösung gefunden. Hat jemand einen tollen Vorschlag?

Ein Interface soll als abstrakte Klasse definiert werden.

// Basis-Interface
class IBase
{
public:
virtual void BaseFunc() = 0;
};

// eins der vielen Applikations-Interfacen
class IApp : public IBase
{
public:
virtual void AppFunc() = 0;
};

Da ich viele Interfacen habe, möchte ich die Funktion BaseFunc in einer
gemeinsamen Klasse implementieren und in den Applikations-Interfacen erben.
Leider funktioniert das nicht:

class Base : public IBase
{
void BaseFunc() { } // overwrite IBase::BaseFunc
};

class App : public Base, public IApp // ups! Mehrfachvererbung von IBase
{
void AppFunc() { } // overwrite IApp:AppFunc
};

Die Klasse App ist immer noch mit der pure-virtuellen Methode BaseFunc
behaftet, die ein Instantiiieren von App verhindert. Fehlermeldung:

Instanz von abstrakter Klasse kann aufgrund nachfolgender Elemente nicht
erstellt werden:
Siehe Deklaration von 'App':
Rein virtuelle Funktion wurde nicht definiert.
long IBase::BaseFunc(void)
CApp::BaseFunc ist mehrdeutig
kann sein 'BaseFunc' in Basisklasse 'IBase' of base 'IApp' of class 'App'
oder 'BaseFunc' in Basisklasse 'Base' of class 'App'

Habe ich eine Chance, durch Vererbung, evtl. mit Templates die
Implementierung von BaseFunc in die Klass App zu holen?

Gruß, Helge

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Steffen Liersch
Guest





PostPosted: Fri Dec 19, 2003 7:23 am    Post subject: Re: Implementierung in einem Vererbungsweg Reply with quote



Hallo Helge,

Quote:
Die Klasse App ist immer noch mit der pure-virtuellen Methode BaseFunc
behaftet, die ein Instantiiieren von App verhindert. Fehlermeldung:

Instanz von abstrakter Klasse kann aufgrund nachfolgender Elemente nicht
erstellt werden:
Siehe Deklaration von 'App':
Rein virtuelle Funktion wurde nicht definiert.
long IBase::BaseFunc(void)
CApp::BaseFunc ist mehrdeutig
kann sein 'BaseFunc' in Basisklasse 'IBase' of base 'IApp' of class
'App'
oder 'BaseFunc' in Basisklasse 'Base' of class 'App'

warum überschreibst Du nicht einfach noch die fehlende virtuelle Funktion?

class App : public Base, public IApp // ups! Mehrfachvererbung von IBase
{
public: // hattest Du evtl. vergessen
void AppFunc() { }
void BaseFunc() { }
};

Aber eigentlich finde ich dieses Konzept unübersichtlich, denn es gibt 2
Funktionen BaseFunc(). Selbst wenn BaseFunc nicht abstrakt wäre, könntest Du
diese Funktion nie aufrufen, wenn Du sie nicht noch einmal in der Klasse App
definierst. Aber immerhin: das Objekt kannst Du erzeugen.

Durch ein nicht angegebenes public vor dem Überschreiben einer geerbten
public-Funktion, scheint die überschriebene Funktion tatsächlich wieder
privat zu werden. Sehe ich das richtig, dass in einem solchen Fall die
geerbte Klasse nicht mehr Zuweisungskompatibel mit der Basisklasse ist
(trotz public-Klausel in Basisliste)? Solche Effekte sind ja in C++ möglich,
z. B. wenn man die Basisklasse als protected erbt. In Delphi beispielsweise
sind abgeleitete Klassen immer mit ihren Basisklassen kompatibel.

Viele Grüße,
Steffen Liersch

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Hendrik Belitz
Guest





PostPosted: Fri Dec 19, 2003 7:49 am    Post subject: Re: Implementierung in einem Vererbungsweg Reply with quote



Helge Kruse wrote:

Quote:
Hallo,

ich möchte mit Vererbung eine Gruppe von Interfacen implementieren, die
alle von einem gemeinsamen Interface abgeleitet sind. Ich habe hierfür
keine intelligente Lösung gefunden. Hat jemand einen tollen Vorschlag?

Ein Interface soll als abstrakte Klasse definiert werden.

// Basis-Interface
class IBase
{
public:
virtual void BaseFunc() = 0;
};

// eins der vielen Applikations-Interfacen
class IApp : public IBase
{
public:
virtual void AppFunc() = 0;
};

Da ich viele Interfacen habe, möchte ich die Funktion BaseFunc in einer
gemeinsamen Klasse implementieren und in den Applikations-Interfacen
erben. Leider funktioniert das nicht:

class Base : public IBase
{
void BaseFunc() { } // overwrite IBase::BaseFunc
};

class App : public Base, public IApp // ups! Mehrfachvererbung von IBase
{
void AppFunc() { } // overwrite IApp:AppFunc
};

Die Klasse App ist immer noch mit der pure-virtuellen Methode BaseFunc
behaftet, die ein Instantiiieren von App verhindert.

Ich schlage vor, einfach mal die Methoden in den Klassen App und Base als
virtual zu deklarieren; ansonsten kann das ja auch nicht funktionieren Smile
--
Dipl.-Inform. Hendrik Belitz
Central Laboratory of Electronics
Research Center Juelich

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Marcel Müller
Guest





PostPosted: Fri Dec 19, 2003 9:41 am    Post subject: Re: Implementierung in einem Vererbungsweg Reply with quote

Hallo,

Helge Kruse wrote:

Quote:
Hallo,

ich möchte mit Vererbung eine Gruppe von Interfacen implementieren, die alle
von einem gemeinsamen Interface abgeleitet sind. Ich habe hierfür keine
intelligente Lösung gefunden. Hat jemand einen tollen Vorschlag?

Ich korrigiere einfach mal im Zitat (***) ...

Quote:
// Basis-Interface
class IBase
{
public:
virtual void BaseFunc() = 0;
};

// eins der vielen Applikations-Interfacen
class IApp : public ***virtual*** IBase
{
public:
virtual void AppFunc() = 0;
};

Da ich viele Interfacen habe, möchte ich die Funktion BaseFunc in einer
gemeinsamen Klasse implementieren und in den Applikations-Interfacen erben.
Leider funktioniert das nicht:

class Base : public ***virtual*** IBase
{
void BaseFunc() { } // overwrite IBase::BaseFunc
};

class App : public Base, public ***virtual*** IApp // *** nur eine Instanz von IBase
{
void AppFunc() { } // overwrite IApp:AppFunc
};

Das sollte gehen.

Um eine mit Java vergleichbare Interface-Logik zu erhalten muß man von
Interfaces mit virtual erben.
Das dritte virtual bei App::IApp ist hier im Prinzip überflüssig,
solange man nicht mit IApp eine Ebene höher dasselbe Spiel treibt.

Eine andere Möglichkeit für Implementierungen durch erben ist über
kleine template Helper-Klassen, deren template-Argumente die Basisklasse
und eine Implementierungsklasse ist. Diese Methode erzeugt keinen
schönen Code, ist aber performanter, da auf die virtuelle Vererbung
verzichtet werden kann. Diese Kostet auf üblichen PC-Architekturen
(genauso wie virtual function calls) gerne mal den Inhalt der
CPU-Befehls-Queue (bis zu 20 Takte). Außerdem kann man auf diesem Weg
auch partielle Interfaces durch vererben Implementieren, falls man das
Interafce selbst nicht splitten kann/darf (fremder Code).

class IApp : public ***virtual*** IBase
{public:
virtual void AppFunc() = 0;
};

class Base // diesmal nicht! : public ***virtual*** IBase
{public:
void BaseFunc() { } // muß nichtmal virtuell sein, kann aber
}

template <typename base, typename implementation>
class BaseImplementer
{public:
virtual void BaseFunc() { implementation::foo(); }
}

class App : BaseImplementer<IApp, Base>
{public:
void AppFunc() { } // overwrite IApp:AppFunc, implizit virtuell
}

Die Basisklasse von BaseImplementer muß kein Interface sein, es kann
jede X-beliebige Klasse mit einer vituellen Funktion BaseFunc sein.
Dadurch kann man solche Templates, die dann verschiedene Funktionen
implementieren, auch schachteln (sehr praktisch).
Theoretisch könnte man Base auch in BaseImplementer verschmelzen, dann
würde aber der Code von BaseFunc für jede verschiedene Instanziierung
von BaseImplementer neu generiert, was natürlich das Programm unnötig
aufbläht und die Cacheeffizienz schmälert.
--
Marcel Müller

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Norbert Riedlin
Guest





PostPosted: Fri Dec 19, 2003 11:45 am    Post subject: Re: Implementierung in einem Vererbungsweg Reply with quote

"Helge Kruse" <Helge.Kruse-nospam (AT) gmx (DOT) net> wrote

Quote:

// eins der vielen Applikations-Interfacen
class IApp : public IBase
{
public:
virtual void AppFunc() = 0;
};

Wozu ist IApp von IBase abgeleitet? Lass' das weg und es sollte funktionieren.


HTH

Norbert

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Christoph Rabel
Guest





PostPosted: Fri Dec 19, 2003 12:09 pm    Post subject: Re: Implementierung in einem Vererbungsweg Reply with quote

Hendrik Belitz wrote:
Quote:

Die Klasse App ist immer noch mit der pure-virtuellen Methode BaseFunc
behaftet, die ein Instantiiieren von App verhindert.

Ich schlage vor, einfach mal die Methoden in den Klassen App und Base als
virtual zu deklarieren; ansonsten kann das ja auch nicht funktionieren Smile

Nein. Das virtual ist implizit durch die Deklaration in der
Basisklasse vorgegeben.

Allerdings ist es wirklich schöner das virtual
dazuzuschreiben, damit man es auch beim drüberlesen sieht.

mfg

Christoph

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
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.