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 

Überladen und Überschreiben

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





PostPosted: Wed Mar 16, 2005 12:13 pm    Post subject: Überladen und Überschreiben Reply with quote



Hi,

folgendes Problem ärgert mich schon eine ganze Weile. Dabei kommen mir
die dahinterstehenden Mechanismen gerade für den folgenden Fall eher
kontraintuitiv vor. Erstmal ein bisschen C++:

#include <iostream>

struct A {};
struct B {};

class Base
{
public:
virtual void bla (const A& a) = 0;
virtual void bla (const B& a) = 0;
};

class D1 : public Base
{
public:
virtual void bla (const A& a) { std::cout << "a calledn"; }
};

class D2 : public D1
{
public:
virtual void bla (const B& a) { std::cout << "b calledn"; }
};

int main()
{
D2 x;
static_cast x.bla (A()); // Compilererror
x.bla (B());
std::cin.ignore();
}

Es ist klar, was passiert: in D1 wird 'bla (const A&)' überschrieben,
gleichzeitg aber auch 'bla (const B&)' überdeckt. In D2 wird
entsprechend durch das Überschreiben von 'bla (const B&)' dann 'bla
(const A&)' überdeckt.
Solange die Funktionen nicht virtuell sind, sind mir das Verhalten und
die dahinterstehenden Ideen klar: die Funktionen werden ja nicht
überschrieben, sondern eigentlich überladen und dadurch findet die
Verdeckung statt. Aber gerade bei mehreren virtuellen Funktionen
innerhalb einer Basisklasse ist doch eine Idee dahinter, die durch die
virtuellen Funktionen geschaffenen 'Slots' in der darüberliegenden
Hierarchie _schrittweise_ auszufüllen. Auch findet in diesem Fall ja
kein Überladen, sondern eigentlich ein Überschreiben statt. Warum also
gelten trotzdem die Verdeckungsregeln? Und findet/fand das noch jemand
bisher problematisch?


MfG
Olaf Krzikalla

--
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
Thomas Maeder
Guest





PostPosted: Wed Mar 16, 2005 1:54 pm    Post subject: Re: Überladen und Überschreiben Reply with quote



Olaf Krzikalla <Entwicklung (AT) reico (DOT) de> writes:

Quote:
#include <iostream

#include

Quote:
struct A {};
struct B {};

class Base
{
public:
virtual void bla (const A& a) = 0;
virtual void bla (const B& a) = 0;
};

class D1 : public Base
{
public:
virtual void bla (const A& a) { std::cout << "a calledn"; }
};

class D2 : public D1
{
public:
virtual void bla (const B& a) { std::cout << "b calledn"; }
};

int main()
{
D2 x;
static_cast x.bla (A()); // Compilererror
x.bla (B());
std::cin.ignore();
}

Es ist klar, was passiert: in D1 wird 'bla (const A&)' überschrieben,
gleichzeitg aber auch 'bla (const B&)' überdeckt. In D2 wird
entsprechend durch das Überschreiben von 'bla (const B&)' dann 'bla
(const A&)' überdeckt.
Solange die Funktionen nicht virtuell sind, sind mir das Verhalten und
die dahinterstehenden Ideen klar: die Funktionen werden ja nicht
überschrieben, sondern eigentlich überladen und dadurch findet die
Verdeckung statt. Aber gerade bei mehreren virtuellen Funktionen
innerhalb einer Basisklasse ist doch eine Idee dahinter, die durch die
virtuellen Funktionen geschaffenen 'Slots' in der darüberliegenden
Hierarchie _schrittweise_ auszufüllen. Auch findet in diesem Fall ja
kein Überladen, sondern eigentlich ein Überschreiben statt. Warum also
gelten trotzdem die Verdeckungsregeln?

Vermutlich, weil das bisher nie jemand problematisch genug fand.


Quote:
Und findet/fand das noch jemand bisher problematisch?

Ich nicht. Jeder Compiler gibt hier eine verständliche
Fehlermeldung. Und die Lösung (je eine using-Deklaration in D1 und D2)
ist so einfach, dass ich das nicht wirklich problematisch finde.


Schon problematischer ist die Situtation, wenn Argumenttypen verwendet
werden, welche implizit ineinander konvertierbar sind. Denn dann wird
u.U. nicht die erwartete Funktion aufgerufen. Solche Situationen sind
deshalb zu vermeiden.

--
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
Olaf Krzikalla
Guest





PostPosted: Wed Mar 16, 2005 2:51 pm    Post subject: Re: Überladen und Überschreiben Reply with quote



Hi,

Thomas Maeder schrieb:
Quote:
#include
#include Jaaa, ich weiß (istream eigentlich auch noch, ich verwende schließlich

auch cin.ignore) *scnr*

Quote:
[...]
Und findet/fand das noch jemand bisher problematisch?

Ich nicht. Jeder Compiler gibt hier eine verständliche
Fehlermeldung. Und die Lösung (je eine using-Deklaration in D1 und D2)
ist so einfach, dass ich das nicht wirklich problematisch finde.
Ich hätte vielleicht schon im ersten Posting mal auch den pragmatischen

Teil des Problems ansprechen sollen: nicht der Fehler ist es (soetwas
muß man soundso in den Griff kriegen), sondern die nervigen Warnungen
bei der Definiton von D1 und D2 sind es (ca. 'D1::bla hides Base::bla').
Mit 'using' kriegt man die zwar auch weg, aber erklär mal jemandem den
Sinn dahinter. Und wenn man das einfach so vorgesetzt kriegst, hast Du
überall da (IMHO eben sinnlose) Warnungen, wo Du die Defnition von D1,
D2 etc. brauchst.


MfG
Olaf Krzikalla

--
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
Karl Heinz Buchegger
Guest





PostPosted: Wed Mar 16, 2005 2:55 pm    Post subject: Re: Überladen und Überschreiben Reply with quote

Olaf Krzikalla wrote:
Quote:

Hi,

folgendes Problem ärgert mich schon eine ganze Weile. Dabei kommen mir
die dahinterstehenden Mechanismen gerade für den folgenden Fall eher
kontraintuitiv vor.

Solche Dinge gibt es in jedem hinreichend grossem Regelwerk. Es wird
immer spezielle Faelle geben, die irgendjemand kontraintuitiv vorkommen.

Quote:
Solange die Funktionen nicht virtuell sind, sind mir das Verhalten und
die dahinterstehenden Ideen klar: die Funktionen werden ja nicht
überschrieben, sondern eigentlich überladen und dadurch findet die
Verdeckung statt. Aber gerade bei mehreren virtuellen Funktionen
innerhalb einer Basisklasse ist doch eine Idee dahinter, die durch die
virtuellen Funktionen geschaffenen 'Slots' in der darüberliegenden
Hierarchie _schrittweise_ auszufüllen.

Nur das in diesem Fall die Virtualitaet ja voellig fuer die Katz ist.
Der Compiler denkt nicht eine Nanosekunde daran, da irgendwas mit
virtuellen Funktionen zu veranstalten. Wozu auch? Der tatsaechliche
Datentyp ist bekannt, also kommt ein stink normaler Methodenaufruf
zum Zug. Und der kann halt nicht befriedigend aufgeloest werden.

Quote:
Und findet/fand das noch jemand
bisher problematisch?

Ich wuerde es viel problematischer finden, wenn ein Regelwerk mit
zig Ausnahmen gespickt wird, nur weil etwas in manchen Situationen,
wie hast Du Dich ausgedrueckt, kontraintuitiv ist. Genau aus diesem
Grund halte ich u.A. die "main-braucht-kein-return-0-,-obwohl-vom-Typ-int"
Ausnahme fuer ziemlich besch.....

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
dietmar_kuehl@yahoo.com
Guest





PostPosted: Wed Mar 16, 2005 3:59 pm    Post subject: Re: Überladen und Überschreiben Reply with quote

Olaf Krzikalla wrote:
Quote:
Solange die Funktionen nicht virtuell sind, sind mir das Verhalten
und
die dahinterstehenden Ideen klar: die Funktionen werden ja nicht
überschrieben, sondern eigentlich überladen und dadurch findet die
Verdeckung statt. Aber gerade bei mehreren virtuellen Funktionen
innerhalb einer Basisklasse ist doch eine Idee dahinter, die durch
die
virtuellen Funktionen geschaffenen 'Slots' in der darüberliegenden
Hierarchie _schrittweise_ auszufüllen. Auch findet in diesem Fall ja
kein Überladen, sondern eigentlich ein Überschreiben statt. Warum
also
gelten trotzdem die Verdeckungsregeln? Und findet/fand das noch
jemand
bisher problematisch?

Wieso sollten die Verdeckungsregeln nicht gelten? Die Auflösung,
welche
überladene Funktion aufgerufen wird, hat nichts damit zu tun, dass die
Funktion virtuell ist! Als erstes wird der korrekte Slot identifiziert
und dann wird, so die gewählte Funktion denn virtuell ist,
festgestellt,
welche überschriebene Funktion denn nun real aufgerufen werden soll.

Wenn man mehrere virtuelle Funktionen überladen hat (nicht
überschrieben,
d.h. es gibt virtuelle Funktionen mit gleichem Namen aber
unterschiedlichen Signaturen), die ggf. einzeln überschrieben werden,
dann bietet es sich spätestens an, die virtuellen Funktion 'private'
zu machen und je eine 'public' Funktion zu definieren, die zu der
entsprechenden 'private' Funktion delegiert. Das ist sogar dann
sinnvoll,
wenn die Funktionen nicht überladen sind: ggf. kann man zentral etwas
Preprocessing oder Postprocessing betreiben. Für die virtuellen
Funktionen in der Standardbibliothek (in den Facets bzw. in den Stream
Buffern) ist das [fast] so gemacht (allerdings sind die virtuellen
Funktionen dort 'protected').
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

--
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.