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 

this im Konstruktor

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





PostPosted: Wed Sep 15, 2004 7:08 am    Post subject: this im Konstruktor Reply with quote



Wieso funktioniert der folgende Code ohne Warnung oder Fehler?

Ich übergebe im mike Konstruktor ein "this" an eine andere Klasse.

Wenn jetzt im mike Konstruktor nach der this Übergabe eine Ausnahme
ausgelöst wird ist das Objekt ungültig

und in feuer wird auf unreferenzierten Speicher verwiesen.

Ich glaube ich habe dazu mal was im Stroustrup gelesen, finde die Stelle
aber nicht mehr.



//CODE

class mike;

class feuer

{

public:

feuer(mike *i) { o=i; }

mike *o;

};

class mike

{

public:

mike() { fff=new feuer(this); }

feuer *fff;

~mike() { delete fff; }

};



int _tmain(int argc, _TCHAR* argv[])

{

mike *p=new mike();

delete p;

return 0;

}

--
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 Sattler
Guest





PostPosted: Wed Sep 15, 2004 1:46 pm    Post subject: Re: this im Konstruktor Reply with quote



Mike Podonyi wrote:

Quote:
class mike
{
public:
mike() { fff=new feuer(this); }
feuer *fff;
~mike() { delete fff; }
};

AFAIK gibt es das Objekt erst _nachdem_ der Konstruktor für selbiges fertig
ist. Somit zeigt auch der Zeiger this im Konstruktor selbst noch nicht auf
eine gültiges Objekt.

HS

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Sep 15, 2004 2:09 pm    Post subject: Re: this im Konstruktor Reply with quote



Hendrik Sattler wrote:
Quote:
Mike Podonyi wrote:

class mike
{
public:
mike() { fff=new feuer(this); }
feuer *fff;
~mike() { delete fff; }
};

AFAIK gibt es das Objekt erst _nachdem_ der Konstruktor für selbiges fertig
ist. Somit zeigt auch der Zeiger this im Konstruktor selbst noch nicht auf
eine gültiges Objekt.

Damit kommt § 3.8/5 zur Anwendung: die Verwendung des Zeigers
ist mit Einschränkungen erlaubt, d.h. er darf nicht dazu benutzt
werden, auf nichtstatische Memberdaten zuzugreifen oder nichtstatische
Memberfunktionen aufzurufen, und er darf weder implizit in einen
Basisklassenzeiger konvertiert werden, noch per static_cast (außer
in void*) oder per dynamic_cast konvertiert werden. Ein Lvalue,
der durch Dereferenzieren aus einem solchen Zeiger entstanden ist,
darf nicht in einen Rvalue umgewandelt (also gelesen) werden.

Wenn also der Konstruktor von 'feuer' den übergebenen 'mike'-Zeiger
nur abspeichert bzw. ihn nur dazu dereferenziert, um ihn an eine
'mike'-Referenz zu binden, gibt's keine Probleme. Sinngemäß für
den Destruktor.

MfG
Falk

--
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 Sattler
Guest





PostPosted: Wed Sep 15, 2004 2:54 pm    Post subject: Re: this im Konstruktor Reply with quote

Falk Tannhäuser wrote:

Quote:
Hendrik Sattler wrote:
Mike Podonyi wrote:

class mike
{
public:
mike() { fff=new feuer(this); }
feuer *fff;
~mike() { delete fff; }
};

AFAIK gibt es das Objekt erst _nachdem_ der Konstruktor für selbiges
fertig ist. Somit zeigt auch der Zeiger this im Konstruktor selbst noch
nicht auf eine gültiges Objekt.

Damit kommt § 3.8/5 zur Anwendung: die Verwendung des Zeigers
ist mit Einschränkungen erlaubt, d.h. er darf nicht dazu benutzt
werden, auf nichtstatische Memberdaten zuzugreifen oder nichtstatische
Memberfunktionen aufzurufen,

Den Zugriff auf statische Variablen oder Funktionen der Klasse könnte man
dann aber billiger haben, dazu braucht man den Zeiger ja net.

Quote:
und er darf weder implizit in einen
Basisklassenzeiger konvertiert werden, noch per static_cast (außer
in void*) oder per dynamic_cast konvertiert werden.

Also kurz: darf garnicht dazu benutzt werden, um irgendeine nicht-statische
Funktion der Basisklasse von Mike aufzurufen?

Quote:
Ein Lvalue,
der durch Dereferenzieren aus einem solchen Zeiger entstanden ist,
darf nicht in einen Rvalue umgewandelt (also gelesen) werden.

Ui, kann mir mal jemand einige dieser Begriffe näherbringen?
Was ist Lvalue und was ist Rvalue?
Wenn man den Wert nicht lesen darf, wieso sollte man ihn dann überhaupt
irgendwo hinschreiben?

Quote:
Wenn also der Konstruktor von 'feuer' den übergebenen 'mike'-Zeiger
nur abspeichert bzw. ihn nur dazu dereferenziert, um ihn an eine
'mike'-Referenz zu binden, gibt's keine Probleme. Sinngemäß für
den Destruktor.

Gibt es dazu ein einfaches Beispiel?

Danke...

HS

--
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: Wed Sep 15, 2004 4:07 pm    Post subject: Re: this im Konstruktor Reply with quote

Hendrik Sattler wrote:

Quote:
Ui, kann mir mal jemand einige dieser Begriffe näherbringen?
Was ist Lvalue und was ist Rvalue?

Lvalue< = >Rvalue<;

Lvalues kann man zuweisen, Rvalues sind read-only.

i.a. sind alle Konstanten und Funktionsrückgabewerte (auch von
operatoren) Rvalues, es sei denn es sind Referenzen.

(int) := Cast auf Rvalue
(int&) := Cast auf Lvalue (sofern erlaubt)


Quote:
Wenn man den Wert nicht lesen darf, wieso sollte man ihn dann überhaupt
irgendwo hinschreiben?

Der Pointer wird in Zukunft gültig werden.

Normalerweise ist es schlechter Programmierstil, aber es gibt
Situationen, in denen das sinnvoll ist.


Quote:
Gibt es dazu ein einfaches Beispiel?

class myClass
{public:

static std::set
myClass()
{ // constructor logic here
alleObjekte.insert(this);
}

~myClass()
{ alleInstanzen.erase(this);
// destructor logic here
}

};


Marcel

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Sep 15, 2004 6:33 pm    Post subject: Re: this im Konstruktor Reply with quote

Hendrik Sattler wrote:
Quote:
Falk Tannhäuser wrote:
und er darf weder implizit in einen
Basisklassenzeiger konvertiert werden, noch per static_cast (außer
in void*) oder per dynamic_cast konvertiert werden.

Also kurz: darf garnicht dazu benutzt werden, um irgendeine nicht-statische
Funktion der Basisklasse von Mike aufzurufen?

Weder von einer Basisklasse, noch von Mike selbst.

Quote:

Ein Lvalue,
der durch Dereferenzieren aus einem solchen Zeiger entstanden ist,
darf nicht in einen Rvalue umgewandelt (also gelesen) werden.

Ui, kann mir mal jemand einige dieser Begriffe näherbringen?
Was ist Lvalue und was ist Rvalue?
Wenn man den Wert nicht lesen darf, wieso sollte man ihn dann überhaupt
irgendwo hinschreiben?

Erstmal zur letzten Frage:
Der Zweck des ganzen ist es, den Zeiger auf das noch nicht vollständig
konstruierte Objekt irgendwo zu speichern (bzw. den dereferenzierten
Zeiger [= Lvalue] an eine Referenz zu binden, welche gespeichert wird, was auf
das gleiche hinausläuft), um ihn später (wenn die Konstruktion abgeschlossen
ist) normal zu verwenden.

Lvalues und Rvalues:
Jeder Ausdruck in C++ (und C) ist entweder ein Lvalue oder ein Rvalue.
Lvalues sind (etwas vereinfacht) Ausdrücke, die sich auf Objekte beziehen.
Demgegenüber sind Rvalues Werte, die keine Identität besitzen, also
i.d.R. keine Objekte (*).

Beispiel: Hat man
int i = 1664;
int* pi = &i;
int& ri = i;
std::vector<int> v(666);
struct foo { char cc; int ii; }; foo f;

so sind 'i', '*pi', 'ri', 'v[42]' und 'f.ii' Lvalues vom Typ 'int', während
'0', '-42', '+i', 'v[42] * f.ii - *pi / ri' Rvalues sind.

Der spracheigene Zuweisungsoperator '=' erwartet auf seiner *l*inken
Seite einen Lvalue und auf seiner *r*echten einen Rvalue, daher die
Namen (von Englisch "left" / "right", um genau zu sein).
Z.B.
*pi = -42;
(Umgekehrt kann nicht jeder Lvalue links von '=' auftauchen, da Lvalues
'const' sein können, z.B. 'int const ci = 4711;' - damit geht nicht
'ci = 0;'.)
Weiterhin kann man von Lvalues stets die Adresse bestimmen, aber
nie von Rvalues. Lvalues lassen sich an Referenzen binden (konstante
ohne Cast natürlich nur an const-qualifizierte), Rvalues nur an
const-qualifizierte Referenzen (wobei dann ein temporäres
Objekt geschaffen wird).

Außerdem werden Lvalues, die in einem Kontext auftreten, wo Rvalues
verlangt sind, stets in letztere umgewandelt, z.B.:
v[42] = i;

Hier ist 'i' ein Lvalue, aber '=' verlangt rechts einen Rvalue.
Also wird 'i' in einen Rvalue umgewandelt, d.h. der in 'i' stehende
Wert gelesen, um dann an den Lvalue 'v[42]' zugewiesen zu werden.

Dagegen findet im ähnlich aussehenden
int& ri = i;
keine solche Umwandlung statt, sondern der Lvalue 'i' wird nur an
die Referenz 'ri' gebunden.

Alle Klarheiten beseitigt?

Quote:

Wenn also der Konstruktor von 'feuer' den übergebenen 'mike'-Zeiger
nur abspeichert bzw. ihn nur dazu dereferenziert, um ihn an eine
'mike'-Referenz zu binden, gibt's keine Probleme. Sinngemäß für
den Destruktor.

Gibt es dazu ein einfaches Beispiel?
______________________________________________________________________

#include <iostream>
#include <ostream>
#include <string>

struct Partner
{
std::string name;
Partner& mein_partner;

Partner(std::string const& n, Partner& p)
: name(n),
mein_partner(p)
{
//mein_partner.knutsche(); // <=== Problem 1
}

~Partner()
{
//mein_partner.woatschn(); // <=== Problem 2
}

void knutsche() { std::cout << "Schmatz für " << name << "!n"; }
void woatschn() { std::cout << "Klatsch für " << name << "!n"; }
};

struct Paar
{
Partner er;
Partner sie;

Paar(std::string const& n1, std::string const& n2)
: er(n1, sie),
sie(n2, er)
{
er. mein_partner.knutsche();
sie.mein_partner.knutsche();
}

~Paar()
{
sie.mein_partner.woatschn();
er. mein_partner.woatschn();
}
};

int main()
{
Paar p("Gerhard", "Doris");
std::cout << "Hello world!n";
return 0;
}
______________________________________________________________________

Dieses Programm ist wohldefiniert, es sei denn, eine der beiden
kommentierten Zeilen wird mit reingenommen.

Wenn der Konstruktor von 'Paar' aufgerufen wird wird, wird zunächst 'er'
konstruiert, dann 'sie', schließlich wird der Konstruktorkörper (zwischen
den geschweiften Klammern) ausgeführt.
Der Konstruktor von 'Paar' übergibt nun an den für 'er' aufgerufenen
Konstruktor von 'Partner' eine Referenz auf 'sie' - ein 'Partner'-Objekt,
das zu diesem Zeitpunkt noch gar nicht existiert, dessen Adresse aber
schon feststeht, weil der Speicherplatz sich im 'Paar'-Objekt befindet.
Das Binden des noch nicht konstruierten 'sie' an die Referenz 'mein_partner'
in 'er' ist nach §§ 3.8/5-6 erlaubt, nicht aber der mit "Problem 1"
gekennzeichnete Methodenaufruf (führt bei mir übrigens zum Programm-
absturz mit "Signal 11" - eben eine Manifestierung von nicht definiertem
Verhalten).
Ähnliches im Destruktor - entkommentiere ich bei mir die mit "Problem 2"
gekennzeichnete Zeile, gibt das Programm Müll aus und stürzt ab -
nach der Ausführung des Destruktorkörpers von '~Paar()' wird zunächst
der Destruktor von 'sie' ausgeführt (während 'er' noch existiert -
also kein Problem), dann der von 'er' ('sie' ist schon zerstört -
also nicht definiertes Verhalten beim Methodenaufruf).

Dagegen sind die Aufrufe im Konstruktorkörper von 'Paar' OK -
beide Felder 'er' und 'sie' existieren dort schon.


MfG
Falk

*) Ja, es gibt auch Ausnahmen - Rvalues mit Klassentyp, die sich auf Objekte
beziehen - sonst wäre die Sprache zu einfach Smile
Beispiel:
std::string haha() { return "Haha"; }

Hier stellt 'haha()' ein temporäres Objekt dar, dessen Memberfunktionen
aufgerufen werden können, z.B.
unsigned u = haha().size();
aber das trotzdem ein Rvalue ist. So sind
std::string* ps = &foo();
oder
std::string& rs = foo();
nicht erlaubt.

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Sep 15, 2004 6:43 pm    Post subject: Re: this im Konstruktor Reply with quote

Hendrik Sattler wrote:

Quote:
Falk Tannhäuser wrote:

und er darf weder implizit in einen Basisklassenzeiger konvertiert werden, noch per static_cast (außer
in void*) oder per dynamic_cast konvertiert werden.


Also kurz: darf garnicht dazu benutzt werden, um irgendeine nicht-statische
Funktion der Basisklasse von Mike aufzurufen?


Weder von einer Basisklasse, noch von Mike selbst.

Quote:

Ein Lvalue, der durch Dereferenzieren aus einem solchen Zeiger entstanden ist,
darf nicht in einen Rvalue umgewandelt (also gelesen) werden.


Ui, kann mir mal jemand einige dieser Begriffe näherbringen?
Was ist Lvalue und was ist Rvalue?
Wenn man den Wert nicht lesen darf, wieso sollte man ihn dann überhaupt
irgendwo hinschreiben?


Erstmal zur letzten Frage:
Der Zweck des ganzen ist es, den Zeiger auf das noch nicht vollständig
konstruierte Objekt irgendwo zu speichern (bzw. den dereferenzierten
Zeiger [= Lvalue] an eine Referenz zu binden, welche gespeichert wird, was auf
das gleiche hinausläuft), um ihn später (wenn die Konstruktion abgeschlossen
ist) normal zu verwenden.

Lvalues und Rvalues:
Jeder Ausdruck in C++ (und C) ist entweder ein Lvalue oder ein Rvalue.
Lvalues sind (etwas vereinfacht) Ausdrücke, die sich auf Objekte beziehen.
Demgegenüber sind Rvalues Werte, die keine Identität besitzen, also
i.d.R. keine Objekte (*).

Beispiel: Hat man
int i = 1664;
int* pi = &i;
int& ri = i;
std::vector<int> v(666);
struct foo { char cc; int ii; }; foo f;

so sind 'i', '*pi', 'ri', 'v[42]' und 'f.ii' Lvalues vom Typ 'int', während
'0', '-42', '+i', 'v[42] * f.ii - *pi / ri' Rvalues sind.

Der spracheigene Zuweisungsoperator '=' erwartet auf seiner *l*inken
Seite einen Lvalue und auf seiner *r*echten einen Rvalue, daher die
Namen (von Englisch "left" / "right", um genau zu sein).
Z.B.
*pi = -42;
(Umgekehrt kann nicht jeder Lvalue links von '=' auftauchen, da Lvalues
'const' sein können, z.B. 'int const ci = 4711;' - damit geht nicht
'ci = 0;'.)
Weiterhin kann man von Lvalues stets die Adresse bestimmen, aber
nie von Rvalues. Lvalues lassen sich an Referenzen binden (konstante
ohne Cast natürlich nur an const-qualifizierte), Rvalues nur an
const-qualifizierte Referenzen (wobei dann ein temporäres
Objekt geschaffen wird).

Außerdem werden Lvalues, die in einem Kontext auftreten, wo Rvalues
verlangt sind, stets in letztere umgewandelt, z.B.:
v[42] = i;

Hier ist 'i' ein Lvalue, aber '=' verlangt rechts einen Rvalue.
Also wird 'i' in einen Rvalue umgewandelt, d.h. der in 'i' stehende
Wert gelesen, um dann an den Lvalue 'v[42]' zugewiesen zu werden.

Dagegen findet im ähnlich aussehenden
int& ri = i;
keine solche Umwandlung statt, sondern der Lvalue 'i' wird nur an
die Referenz 'ri' gebunden.

Alle Klarheiten beseitigt?

Quote:


Wenn also der Konstruktor von 'feuer' den übergebenen 'mike'-Zeiger
nur abspeichert bzw. ihn nur dazu dereferenziert, um ihn an eine
'mike'-Referenz zu binden, gibt's keine Probleme. Sinngemäß für
den Destruktor.


Gibt es dazu ein einfaches Beispiel?

______________________________________________________________________
#include <iostream>
#include <ostream>
#include <string>

struct Partner
{
std::string name;
Partner& mein_partner;

Partner(std::string const& n, Partner& p)
: name(n),
mein_partner(p)
{
// mein_partner.knutsche(); // <=== Problem 1
}

~Partner()
{
// mein_partner.woatschn(); // <=== Problem 2
}

void knutsche() { std::cout << "Schmatz für " << name << "!n"; }
void woatschn() { std::cout << "Klatsch für " << name << "!n"; }
};

struct Paar
{
Partner er;
Partner sie;

Paar(std::string const& n1, std::string const& n2)
: er(n1, sie),
sie(n2, er)
{
er. mein_partner.knutsche();
sie.mein_partner.knutsche();
}

~Paar()
{
sie.mein_partner.woatschn();
er. mein_partner.woatschn();
}
};

int main()
{
Paar p("Gerhard", "Doris");
std::cout << "Hello world!n";
return 0;
}
______________________________________________________________________

Dieses Programm ist wohldefiniert, es sei denn, eine der beiden
kommentierten Zeilen wird mit reingenommen.

Wenn der Konstruktor von 'Paar' aufgerufen wird wird, wird zunächst 'er'
konstruiert, dann 'sie', schließlich wird der Konstruktorkörper (zwischen
den geschweiften Klammern) ausgeführt.
Der Konstruktor von 'Paar' übergibt nun an den für 'er' aufgerufenen
Konstruktor von 'Partner' eine Referenz auf 'sie' - ein 'Partner'-Objekt,
das zu diesem Zeitpunkt noch gar nicht existiert, dessen Adresse aber
schon feststeht, weil der Speicherplatz sich im 'Paar'-Objekt befindet.
Das Binden des noch nicht konstruierten 'sie' an die Referenz 'mein_partner'
in 'er' ist nach §§ 3.8/5-6 erlaubt, nicht aber der mit "Problem 1"
gekennzeichnete Methodenaufruf (führt bei mir übrigens zum Programm-
absturz mit "Signal 11" - eben eine Manifestierung von nicht definiertem
Verhalten).
Ähnliches im Destruktor - entkommentiere ich bei mir die mit "Problem 2"
gekennzeichnete Zeile, gibt das Programm Müll aus und stürzt ab -
nach der Ausführung des Destruktorkörpers von '~Paar()' wird zunächst
der Destruktor von 'sie' ausgeführt (während 'er' noch existiert -
also kein Problem), dann der von 'er' ('sie' ist schon zerstört -
also nicht definiertes Verhalten beim Methodenaufruf).

Dagegen sind die Aufrufe im Konstruktorkörper von 'Paar' OK -
beide Felder 'er' und 'sie' existieren dort schon.


MfG
Falk

*) Ja, es gibt auch Ausnahmen - Rvalues mit Klassentyp, die sich auf Objekte
beziehen - sonst wäre die Sprache zu einfach Smile
Beispiel:
std::string haha() { return "Haha"; }

Hier stellt 'haha()' ein temporäres Objekt dar, dessen Memberfunktionen
aufgerufen werden können, z.B.
unsigned u = haha().size();
aber das trotzdem ein Rvalue ist. So sind
std::string* ps = &haha();
oder
std::string& rs = haha();
nicht erlaubt.

--
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 Sattler
Guest





PostPosted: Wed Sep 15, 2004 10:32 pm    Post subject: Re: this im Konstruktor Reply with quote

Falk Tannhäuser wrote:

Quote:
Alle Klarheiten beseitigt?

Yup, danke.

HS

--
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: Thu Sep 16, 2004 8:53 pm    Post subject: Re: this im Konstruktor Reply with quote

"Falk Tannhäuser" <falk.tannhauser (AT) crf (DOT) canon.fr> schrieb im Newsbeitrag
news:ci9ier$ke1$1 (AT) s5 (DOT) feed.news.oleane.net...
Quote:

Damit kommt § 3.8/5 zur Anwendung: die Verwendung des Zeigers
ist mit Einschränkungen erlaubt, d.h. er darf nicht dazu benutzt
werden, auf nichtstatische Memberdaten zuzugreifen oder nichtstatische
Memberfunktionen aufzurufen,

Hm, dann waere also

class C {
private:
int a;
void init()
{
this->a = 42; // Zugriff auf nichtstatischen Member
}
public:
C()
{
this->init(); // Zugriff auf nichtstatische Memberfunktion
}
};

nicht erlaubt? Das kann ich mir aber kaum vorstellen. Wo ein Problem
vorliegen kann, ist
1. in der Initialisierungsliste
2. beim Aufruf von virtuellen Funktionen

Zu 1.: wenn der Original Code so aussaehe:

class mike;

class feuer {
public:
feuer(mike *i) { o=i; }
mike *o;
};

struct ComplexObj {
ComplexObj();
int a;
int b;
};

class mike {
public:
// mike() { fff=new feuer(this); } // Original: Zuweisung im Construktor
Body

mike() : fff(new feuer(this)) {} // Beachte: Initialisierungsliste

ComplexObj co1;
feuer *fff;
ComplexObj co2;

~mike() { delete fff; }
};

Duerfte in feuer::feuer(mike*) nicht auf das mike-Objekt zugegriffen werden,
bzw nur auf
bis zum Zeitpunkt des Aufrufs bereits konstruierte Teile des mike Objektes.
Also waer in
feuer::feuer(mike* m) der Aufruf
m->co1.a = 42;
in Ordnung, allerdings fuehrt
m->co2.a = 42;
zu undefiniertem Verhalten.

zu 2.
Im originalen Beispiel sind alle Teilobjekte des mike-Objektes vollstaendig
konstruiert,
also kann auf alle Teilobjekte zugegriffen werden. Wenn allerdings im
originalen Beispiel
in feuer::feuer(mike*) eine virtuelle Funktion des mike-Objektes aufgerufen
wird, dann
wird _immer_ die Funktion der mike-Klasse aufgerufen und nicht die einer
eventuell
abgeleiteten Klasse:

Beispiel:

class mike {
public:
// bis auf diese Funktion alles wie gehabt:
virtual void fn() {
std::cout << "mike::fn()n";
}
};

class jack : public mike {
public:
virtual void fn() {
std::cout << "jack::fn()n";
}
};

feuer::feuer(mike* m)
{
o = m;
m->fn();
}

int main()
{
mike m;
jack c;
}

Sowohl m als auch c geben "mike::fn()" aus. Das ist eventuell nicht das
erwartete Verhalten,
aber es ist erstens das im Standard definierte Verhalten und zweitens das
politisch
korrekte Verhalten.

Bis dann

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