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 

Endlosschleife

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





PostPosted: Sat Dec 13, 2003 8:01 pm    Post subject: Endlosschleife Reply with quote



void Value::Undefined::operator = (const std::string& s)
{
std::istringstream iS(s);
int i;
if(iS>>i) *this = Value::Integer::Integer(i);
}


Value::Undefined und Value::Integer sind beides Abgeleitete Klassen der
selben Basisklasse. Das da oben bewirkt eine Endlosschleife, bei welcher
obiger Zuweisungsoperator und unten stehender Konstruktor alternieren.

Value::Integer::Integer (const int value):v(value){}

Sinn der Konstruktion war, aus einem Undefined ein Integer zu machen,
wenn sich der an das Undefined zugewiesene String als int ausdrücken läßt.

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





PostPosted: Sat Dec 13, 2003 8:40 pm    Post subject: Re: Endlosschleife Reply with quote




"Georg Maaß" <georg (AT) bioshop (DOT) de> schrieb im Newsbeitrag
news:brfnb0$2r8u3$1 (AT) ID-3551 (DOT) news.uni-berlin.de...
Quote:
void Value::Undefined::operator = (const std::string& s)
{
std::istringstream iS(s);
int i;
if(iS>>i) *this = Value::Integer::Integer(i);
}


Value::Undefined und Value::Integer sind beides Abgeleitete Klassen der
selben Basisklasse. Das da oben bewirkt eine Endlosschleife, bei welcher
obiger Zuweisungsoperator und unten stehender Konstruktor alternieren.

Value::Integer::Integer (const int value):v(value){}

Sinn der Konstruktion war, aus einem Undefined ein Integer zu machen,
wenn sich der an das Undefined zugewiesene String als int ausdrücken läßt.


Ich kann keine Endlosschleife erkennen. Es ist noch nicht einmal eine
enldlose Rekursion.
Es ist der Versuch einem Typ zur Laufzueit eine andere Rolle zu verpassen.
Das ist eine
Sackgasse und führt nicht zum Erfolg. Man wird nie aus einem Flugzeug
während des Fluges
ein Schiff machen können. Ein Flugboot allerdings ist zum fliegen und zum
schwimmen geeignet.
Wesentlich ist, dass schon vor dem ersten Exemplar des Flugzeuges oder des
Flugbootes ein
Plan existiert, dass die Eigenschaften des Geräts spezifiziert.
Der Typ in C++ entspricht diesem Plan. Er spezifiziert die Eigenschaften.
Man kann diese nicht
durch algorithmische Tricks in ein ganz anderes Konzept zwängen.

Ralf

www.cplusplus-kurse.de

--
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
Markus Breuer
Guest





PostPosted: Sun Dec 14, 2003 12:17 am    Post subject: Re: Endlosschleife Reply with quote



Georg Maaß schrieb:
Quote:
void Value::Undefined::operator = (const std::string& s)
{
std::istringstream iS(s);
int i;
if(iS>>i) *this = Value::Integer::Integer(i);
}


Value::Undefined und Value::Integer sind beides Abgeleitete Klassen der
selben Basisklasse. Das da oben bewirkt eine Endlosschleife, bei welcher
obiger Zuweisungsoperator und unten stehender Konstruktor alternieren.

Value::Integer::Integer (const int value):v(value){}

Sinn der Konstruktion war, aus einem Undefined ein Integer zu machen,
wenn sich der an das Undefined zugewiesene String als int ausdrücken läßt.

Da scheint ein konzeptioneller Fehler vorzuliegen! Wenn ich dich richtig
verstehe, soll dein this-Zeiger abhängig vom der Zuweisung die Identität
wechseln. Also "Undefined dummy=123" und dummy ist nach der Zuweisung
ein Integer. Das Problem lässt sich einfach lösen, dazu gleich mehr.

Zuerst einmal gibt dein Zuweisungsoperator einen void zurück, das finde
ich unschön. Besser ist hier eine Referenz auf die Instanz.
Ein zweites Problem sind die polymorphen Zuweisungsoperatoren, sie
kopieren nur den Basisklassenanteil und meisst nicht das, was man gerne
hätte. Schliesslich ist die Basisklasse abstrakt und hat keine
Informationen über die abgeleiteten Klassen.

Um einen Identitätswechsel möglich zu machen, schlage ich vor eine nicht
polymorphe Wrapper-Klasse zu implementieren:

class Wrapper
{
public:
Wrapper() { m_pValue = new Value::undefined; }
// dein Operator
Wrapper& operator=( const std::string& _str )
{
std::istringstream iss(_str);
int zahl;
if ( iss >> zahl )
{
delete m_pValue; m_pValue = new Value::Integer(zahl);
}
else
{
delete m_pValue; m_pValue = new Value::Undefined(_str);
}
}
private:
Value::BaseClass* m_pValue;
};

Das sollte vereinfacht ausgedrückt machen, was du möchtest.

Gruß Markus

--
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
Georg Maaß
Guest





PostPosted: Sun Dec 14, 2003 2:04 pm    Post subject: Re: Endlosschleife Reply with quote

Ralf wrote:
Quote:
Ich kann keine Endlosschleife erkennen. Es ist noch nicht einmal eine
enldlose Rekursion.

Es wurde ja auch keine programmiert. Aber offenbar kommt der Stack
durcheinader, so daß es sich beim Laufen lassen so auswirkt, also ob da
eine Schleife programmiert wäre.

Quote:
Der Typ in C++ entspricht diesem Plan.

Gegen den Plan, "ich schmeiß den Frosch aus dem teich und werf einen
Prinzen rein" ist nichts einzuwenden, wenn neben diesem Plan auch noch
der Plan "ich behalte den Frosch und verwandle ihn in einen Prinzen"
unterstützt wird.

Einen Teich mit Frosch kann ich in einen Teich mit Prinzen wandeln. Für
C++ ist das einfach nur ein Teich implementiert als Wrapperklasse.
--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
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
Georg Maaß
Guest





PostPosted: Sun Dec 14, 2003 2:58 pm    Post subject: Re: Endlosschleife Reply with quote

Markus Breuer wrote:
Quote:
Georg Maaß schrieb:

void Value::Undefined::operator = (const std::string& s)
{
std::istringstream iS(s);
int i;
if(iS>>i) *this = Value::Integer::Integer(i);
}


Value::Undefined und Value::Integer sind beides Abgeleitete Klassen
der selben Basisklasse. Das da oben bewirkt eine Endlosschleife, bei
welcher obiger Zuweisungsoperator und unten stehender Konstruktor
alternieren.

Value::Integer::Integer (const int value):v(value){}

Sinn der Konstruktion war, aus einem Undefined ein Integer zu machen,
wenn sich der an das Undefined zugewiesene String als int ausdrücken
läßt.


Da scheint ein konzeptioneller Fehler vorzuliegen! Wenn ich dich richtig
verstehe, soll dein this-Zeiger abhängig vom der Zuweisung die Identität
wechseln. Also "Undefined dummy=123" und dummy ist nach der Zuweisung
ein Integer. Das Problem lässt sich einfach lösen, dazu gleich mehr.

Zuerst einmal gibt dein Zuweisungsoperator einen void zurück, das finde
ich unschön.

Das war ein Zugeständnis an die Zeilenlänge im Posting. Im Original
liefert er das s also eine Referenz auf den ursprünglichen Wert. Die
Überlegung dabei war war, daß ich weniger verschiedene
Zuweisungsoperatoren implementieren muß, wenn sie immer die Primnitiven
Typen liefern. Ein Rückgabewert wird ja ohenhin nur für die Verkettung
von Zuweisungen benötigt.

a = b = c = "4711";

So müssen die Klassen von a, b und c jeweils nur die Zuweisung von einem
const char* unterstützen, müssen aber nicht die jeweiligen anderen
Klassen kennen bzw. unterstützen.

Wie gesagt, daß da void als Rückgabewert steht, ist ein Zugeständnis an
die Zeilenlänge im Posting und nicht der tatsächliche Rückgabewert im
Original.

Quote:
Um einen Identitätswechsel möglich zu machen, schlage ich vor eine nicht
polymorphe Wrapper-Klasse zu implementieren:

Das hier war die innere Klasse im Bauch der Wrapperklasse. Der Versuch,
es so zu machen, entstammt dem Problem der Speicherallokation. Wenn ich
die Wrapperklasse auf andere Art und Weise erzeuge (z.B. im shared
memory), dann muß sie "wissen", daß sie in einem einzigen Detail anders
ist, und entsprechend auch selbst auf die andere Art Speicher
allokieren. Ich müßte also für jede Art Speicherverwaltung eigene
Klassen implementieren, die sich alle gegenseitig kennen, um
kommunizieren zu können. Das artet dann dermaßen aus und ist überhaupt
nicht pflegbar.

Quote:
Das sollte vereinfacht ausgedrückt machen, was du möchtest.

Ohne die Randbedingung, auch mit unterschiedlichen und gemischten
Speicehrallokationsmechnaismen klarzukommen, tut es das. Meine bisherige
Implementierung geht seit 2½ Jahren auch genau so vor. Aber sie ist
unter dem neuen Aspekt "shared memory" völlig unbrauchbar und auch schon
jetzt aufgebläht und schlecht zu warten. Deshalb suche ich jetzt nach
einer besseren Implementierung.

Das boost::any ist lediglich eine Mehrzweckverpackung. Es ist nicht
wandelbar. Genau das macht einen wesentlichen Unterschied aus. Für viele
Zwecke reicht das völlig aus; aber eben nicht für alle, insbesondere,
wenn die Wandelbarkeit ein Keyfeature ist. Wie das boost::any mit
komplexen, vielfach verzweigten Objekten (also Zeug, das intern map,
vector, list etc nutzt) und "shared memory" umgehen kann, ist unklar. Es
ist anzunehmen, daß es da ebenso flach liegt. Auch wenn hier gerne auf
das boost::any verwiesen wird, so bringt es mir keine wesentlichen
Vorteile, sondern nur eine andere API und zusätzliche Einschränkungen
wie z.B., daß es nicht wandelbar ist.

--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
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
Friedhelm Hoerner
Guest





PostPosted: Tue Dec 16, 2003 8:10 am    Post subject: Re: Endlosschleife Reply with quote

Georg Maaß <georg (AT) bioshop (DOT) de> wrote

Quote:
void Value::Undefined::operator = (const std::string& s)
{
std::istringstream iS(s);
int i;
if(iS>>i) *this = Value::Integer::Integer(i); // (****)
}


Value::Undefined und Value::Integer sind beides Abgeleitete Klassen der
selben Basisklasse. Das da oben bewirkt eine Endlosschleife, bei welcher
obiger Zuweisungsoperator und unten stehender Konstruktor alternieren.

Value::Integer::Integer (const int value):v(value){}

[...]


Ich vermute, daß es einen der Konvertierungsoperatoren der Form:

Value::Integer::Integer::operator std::string ()
Value::Integer::operator std::string ()
Value::operator std::string ()

oder sowas ähnliches gibt, was zu einem std::string führt.
Es wird nämlich in Deiner Zuweisung auf der rechten Seite ein
temporäres Objekt
Value::Integer::Integer tmp(i)
erzeugt, das dann in per obiger Konvertierung vom Compiler in einen
std::string umgewandelt werden kann. Und daraufhin wird dann die
Zuweisung

void Value::Undefined::operator = (const std::string& s)

ausgeführt was zu der Rekursion führt...

Einen Integer kann man durch diese Konstruktion nicht erzeugen - der
Zuweisungsoperator in (****) muß auf der Klasse

Value::Undefined (das ist der Typ von *this)

definiert sein und dort ist *nur* der Zugriff auf diesen Objekttyp
möglich (auch ein default Zuweisungsoperator, vom Compiler evtl. mit
memcpy() generiert wird, kann nur mit der Größe
sizeof(Value::Undefined) ausgeführt werden).
Es gibt in C++ keine volle RTTI Unterstützung wie sizeof(
myRealType(myVar) ).

Gruss Friedhelm

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





PostPosted: Wed Dec 17, 2003 5:03 pm    Post subject: Re: Endlosschleife Reply with quote

Quote:
Gegen den Plan, "ich schmeiß den Frosch aus dem teich und werf einen
Prinzen rein" ist nichts einzuwenden, wenn neben diesem Plan auch noch
der Plan "ich behalte den Frosch und verwandle ihn in einen Prinzen"
unterstützt wird.

Einen Teich mit Frosch kann ich in einen Teich mit Prinzen wandeln. Für
C++ ist das einfach nur ein Teich implementiert als Wrapperklasse.

Dieses Beispiel trifft nicht. Wenn etwas teilweise modifiziert wird, kann
man das
über eine Delegation machen. Dann kann man ein abhängiges Objekt zur
Laufzeit
austauschen. Frosch gegen Prinz, wenn Du willst. Der See bleibt aber ein See
und ändert seinen Typ zur Laufzeit nicht.

Grüße
Ralf


www.oop-trainer.de

--
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
Georg Maaß
Guest





PostPosted: Sun Dec 21, 2003 9:46 pm    Post subject: Re: Endlosschleife Reply with quote

Friedhelm Hoerner wrote:
Quote:
Ich vermute, daß es einen der Konvertierungsoperatoren der Form:

Value::Integer::Integer::operator std::string ()

Den da gibt es, und genau in dem habe ich keinen Debug-Output eingebaut,
sonst wäre mir das aufgefallen, daß der auch aufgerufen wird. Jetzt habe
ich da Debug-Output rein, und jetzt bekennt er sich auch brav zu seiner
Untat.

Wieso wird der überhaupt aufgerufen? Es sind doch gar keine
Elementartypen im Spiel. Ich dachte immer nur Elementartypen wie int und
so werden bei Bedarf automatisch in größere Typen umgewandelt. Aber hier
sind ja nur Klassen als Benutzer definierte Typen am Werk. Das Verhalten
hier ist für mich völlig unerwartet.

--
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
Friedhelm Hoerner
Guest





PostPosted: Tue Jan 13, 2004 7:22 am    Post subject: Re: Endlosschleife Reply with quote

Georg Maaß <georg (AT) bioshop (DOT) de> wrote

Quote:
Friedhelm Hoerner wrote:
Ich vermute, daß es einen der Konvertierungsoperatoren der Form:

Value::Integer::Integer::operator std::string ()

Den da gibt es, und genau in dem habe ich keinen Debug-Output eingebaut,
sonst wäre mir das aufgefallen, daß der auch aufgerufen wird. Jetzt habe
ich da Debug-Output rein, und jetzt bekennt er sich auch brav zu seiner
Untat.

Wieso wird der überhaupt aufgerufen? Es sind doch gar keine
Elementartypen im Spiel. Ich dachte immer nur Elementartypen wie int und
so werden bei Bedarf automatisch in größere Typen umgewandelt. Aber hier
sind ja nur Klassen als Benutzer definierte Typen am Werk. Das Verhalten
hier ist für mich völlig unerwartet.

Eine Benutzerdefinierte Umwandlung darf der Compiler automatisch
verwenden. Wenn ich mich richtig erinnere gilt:

Eine implizite Konvertierung besteht aus einer (optionalen)
Standardkonvertierung (Elementartypen int -> long etc.), gefolgt von
einer benutzerdefinierten Konvertierung, gefolgt von einer weiteren
(optionalen) Standardkonvertierung. Wenn es mehrere gleichwertige
Konvertierungen gibt, wird ein Fehler (ambiguous Conversion)
ausgegeben.
Dies tritt z.B auf in folgendem Beispiel:

class X {
public:
operator int();
//...
};
class Y : public X {
public:
operator char();
//...
};
void f(Y& a) {
if (a) // Y::operator char() oder X::operator int()?
{
//...
}
}

Ein Konstrukor kann auch als benutzerdefinierten Konvertierung
herangezogen werden.
Wenn man das Schlüsselwort "explicit" verwendet, dann wird implizite
Verwendung durch den Compiler unterbunden.

explicit Value::Integer::Integer::operator std::string ();

hätte also in Deinem Beispiel dazu geführt daß diue Konvertierung
nicht stattfindet (Und dann der Compiler einen Fehler ausgegeben
hätte, weil er die Zuweisung nicht mehr aufösen kann...)

Gruss Friedhelm

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





PostPosted: Tue Jan 13, 2004 10:06 am    Post subject: Re: Endlosschleife Reply with quote



Friedhelm Hoerner schrieb:

Quote:

Ein Konstrukor kann auch als benutzerdefinierten Konvertierung
herangezogen werden.
Wenn man das Schlüsselwort "explicit" verwendet, dann wird implizite
Verwendung durch den Compiler unterbunden.

explicit Value::Integer::Integer::operator std::string ();

'explicit' ist aber nur bei Konstruktoren erlaubt, nicht bei Umwandlungsoperatoren.

Wenn man den gleichen Effekt wie bei Konstruktoren haben will, so muß man eine Funktion mit einem
passenden Namen schreiben, also etwa:

struct test
{
std::string to_string() const {return std::string("blah");}
};


So macht es z.B. auch die std::string Klasse bei Umwandlung zu einem C-String; die Umwandlung erfolgt
niemals implizit, sondern muß explizit über die 'c_str' - Funktion angefordert werden.


Grüße,

Thomas

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