🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
3 messages
3 total messages Started by Heiner Otterstedt Tue, 15 Aug 1995 10:11
F: Darf man das?
#255
Author: Heiner Otterstedt
Date: Tue, 15 Aug 1995 10:11
35 lines
1233 bytes
Hallo Experten,

eine Frage: Darf ich in C++ eine Funktion einer Klasse
aufrufen, bevor ihr Construktor aufgerufen wurde?

Hier ein kurzes Beispiel:
Etwas aehnliches hat bei mir lange Zeit wunderbar funktioniert, fuehrt
jetzt aber (wahrscheinlich) ploetzlich zu Exceptions.

BTW: Ich weiss, das dieses nicht die feine Programmiererart ist, aber
     es gind in diesem Fall nicht, das Problem (schnell) anders zu loesen.

class A
{
public:
  A();
}

class B
{
public:
  B(){};
  TuWas() { printf("Ich tue jetzt was!"); }
}

A a;
B b;

A::A()
{ b.TuWas();
}

Schon mal Danke fuer eure Muehe, ciao, Heiner

## CrossPoint v3.02 ##
Re: F: Darf man das?
#256
Author: Heiko Zschernitz
Date: Tue, 15 Aug 1995 21:22
85 lines
2720 bytes
In <5ruTxMFqwPB@0otter.link-goe.zerberus.de> H.OTTERSTEDT@LINK-GOE.zerberus.de (Heiner Otterstedt) writes:
>eine Frage: Darf ich in C++ eine Funktion einer Klasse
>aufrufen, bevor ihr Construktor aufgerufen wurde?

>class A
>{
>public:
>  A();
>}

>class B
>{
>public:
>  B(){};
>  TuWas() { printf("Ich tue jetzt was!"); }
>}

>A a;
>B b;

>A::A()
>{ b.TuWas();
>}

Sollte eigentlich keine Probleme geben, solange B::TuWas() auf keine
Elemente von b zugreift. Dann koenntest Du aber auch explizit angeben,
dass B::TuWas() eine statische Funktion ist:

class B
{
public:
   B(){};
   static TuWas() { printf("Ich tue jetzt was!"); }
};

Dann beschwert sich der Compiler, wenn B::TuWas() versehentlich doch auf
Elemente der Klasse zugreift.
Ausserdem koenntest Du dann den Aufruf der Funktion ein wenig umformulieren:

A::A()
{ B::TuWas();
}

Jetzt wird deutlich, dass der TuWas-Aufruf nichts mit dem Objekt b zu tun
hat (auf die darin enthaltenen Daten wird ja nicht zugegriffen).

Was anderes ist es, wenn B::TuWas() tatsaechlich an den Daten von b
herummanipuliert, wie in dem folgenden Beispiel. Dann darf TuWas()
natuerlich nicht statisch sein:

class B
{
   int x;
public:
   B(){};
   TuWas() { x = 1; }
};

A a;
B b;

A::A()
{ b.TuWas();
}

Das sollte meiner Meinung nach aber ebenfalls funktionieren, weil das
Objekt b statisch erzeugt wird. Dann ist der Speicher ja bereits vorhanden
und die Adresse bekannt, wenn b.TuWas() aufgerufen wird.

Uebrigens sollte man sich nicht darauf verlassen, dass die Konstruktoren
von a und b in dieser Reihenfolge aufgerufen werden. Je nach verwendetem
Compiler/Linker kann die Reihenfolge der Initialisierung von statischen
Objekten variieren (vermute ich). Und einige Compiler sind ueberhaupt nicht
in der Lage statische Objekte zu initialisieren. :-(

Da faellt mir gerade auf, dass vielleicht stdout noch nicht initialisiert
ist, wenn der Konstruktor von a aufgerufen wird?! Dann wuerde das printf
natuerlich nicht funktionieren...
(Halte ich aber fuer unwahrscheinlich.)

-- 
     o   GCS/O -d+(?) H++ s-:++ g+ p2 !au a- w+ C++++(---)$ N++   \|/
  _ /<_        W--- po- t++@ R+(+++) b+ e+ h+ n+(----) y+         0 0
_(_)>(_)____________________________________________________/-oOo--v--oOo-\_
Heiko Zschernitz - Bremen - Germany                    hz@andurg.hb.north.de
Re: F: Darf man das?
#272
Author: Michael Mauch
Date: Thu, 17 Aug 1995 17:27
47 lines
2047 bytes
On Tue, 15 Aug 95 23:22:58 +0200, Heiko Zschernitz wrote:

>class B
>{
>   int x;
>public:
>   B(){};
>   TuWas() { x = 1; }
>};

>A a;
>B b;

>A::A()
>{ b.TuWas();
>}

>Das sollte meiner Meinung nach aber ebenfalls funktionieren, weil das
>Objekt b statisch erzeugt wird. Dann ist der Speicher ja bereits vorhanden
>und die Adresse bekannt, wenn b.TuWas() aufgerufen wird.

>Uebrigens sollte man sich nicht darauf verlassen, dass die Konstruktoren
>von a und b in dieser Reihenfolge aufgerufen werden. Je nach verwendetem
>Compiler/Linker kann die Reihenfolge der Initialisierung von statischen
>Objekten variieren (vermute ich). 

Volle Zustimmung: die statischen Objekte werden vom Compiler/Linker "je nach
Laune" irgendwann vor dem Aufruf von main() initialisiert. Wenn ein Programm aus
mehreren Modulen (.OBJ-Dateien unter DOS) besteht, kann es passieren, dass das
Programm einmal laeuft und einmal nicht, je nach der Reihenfolge, in der man die
Module dem Linker vorsetzt. 

Beispiel-Katastrophe: 

Zum Debuggen setzt man sich einen statischen Stream in eines der Module:

ofstream Log("alles.log");

In verschiedenen Modulen verteilt man dann jede Menge statische Objekte, deren
Konstruktoren froehlich in den Log-Stream schreiben. Mit etwas "Glueck" schafft
man es dann, dass das Programm laeuft. Wenn man dann die Anordnung der
OBJ-Dateien beim Aufruf des Linkers etwas veraendert, semmelt das Programm
gnadenlos ab ("komisch, komisch, ich hab doch gar nichts veraendert?!").


Tschuess...
		Michael
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads