c++ member-Funktion wird VOR constructor aufgerufen!1!elf

Gast #4837262
Hallo Forum,

Ich verstehe mal wieder die Welt nicht.

Ich konnte mittels Debugger nach verfolgen, dass hier zuerst 
onDestroy(this, onDestroyAccessor) aufgerufen wird und erst 
anschliessend onDestroyAccessor(). Und das sowohl in einer richtigen 
Klasse, als auch in dieser Testklasse. WARUM???
1
class Test {
2
public:
3
  EventHandle<Test> onDestroy;
4

5
  Test() :
6
    onDestroyAccessor(),
7
    onDestroy(this, onDestroyAccessor) {
8
    printf("Test()\n");
9
  }
10

11
  void destroy() {
12
    onDestroyAccessor.trigger();
13
  }
14

15
private:
16
  EventHandle<Test>::Accessor onDestroyAccessor;
17
};
18

19
int main() {
20
  Test test;
21
  test.destroy();
22
}

Ausschnitt aus der EventHandle-Klasse:
1
template <class T>
2
class EventHandle {
3
public:
4
  class Accessor;
5
  friend class Accessor;
6

7
  EventHandle(T *const obj_, Accessor &accessor_) : obj(obj_) {
8
    accessor_.assignHandle(this);
9
  };
10
// ... etc...
11
}
12

13
template <class T>
14
class EventHandle<T>::Accessor {
15
public:
16
  friend EventHandle;
17
  Accessor() : event_handle(nullptr) { }
18

19
private:
20
  void assignHandle(typename EventHandle::ptr_t event_handle_) {
21
//    assert(!event_handle); <--- schlägt fehl weil constructor nicht aufgerufen wurde!
22
    event_handle = event_handle_;
23
  }
24

25
  virtual void trigger() {
26
//    assert(event_handle); <--- schlägt ebenfalls fehl, weil der constructor
27
//                               event_handle anschliessend wieder auf nullptr gesetzt hat.
28
    event_handle->trigger();
29
  }
30
// ... etc...
31
}

Vielen Dank schon mal für jeden Kommentar.
Gast
DU BIST EIN GENIE! Da wär ich echt im Leben nicht drauf gekommen! Ist 
auch irgendwie extrem unlogisch.
D.h. ich muss bei dieser Klasse die privaten Member immer vor den 
öffentlichen deklarieren. Unschön :(
Gast
Rasputin schrieb:
> Ist auch irgendwie extrem unlogisch.

Nun ja, Destruktoren der Members müssen in umgekehrter Reihenfolge der 
Konstruktoren aufgerufen werden. Da der Destruktor der Klasse als 
einzigen Hinweis die Anordnung der Members in der Klasse hat, muss sich 
der Konstruktor auch nach diesem Hinweis richten. "Logischerweise" 
arbeitete der Konstruktor von oben nach unten in der Member-Liste, und 
der Destruktor von unten nach oben.
Gast
@tictactoe

Guter Hinweis! Das hab ich nicht bedacht. So gesehen ergibt das 
natürlich absolut Sinn.

Horst schrieb:
> Rasputin schrieb:
>> Bei VC++2015 gibt's übrigens keine Warnung.
> Tu dir selbst einen gefallen und benutz was richtiges zur
> Programmierung. Die warnen dann auch sinnvoll.

Ich hab bis vor kurzem cygwin mit gcc benutzt. Aber fand es dann albern. 
Entweder richtig Linux in einer VM oder den offiziellen Compiler von 
Microsoft für Windows.

Aber es ist schon wahr. Wenn ich in Visual Studio /Wall einstelle, 
bekomme ich fast 150 Warnungen, etwa 90% in der Art von

> "int printf(const char *const ,...)": Funktion ist nicht "inline"

alles Warnungen die den std Namensraum betreffen.

Sowie einige

> "foo": 2 Bytes Abstand hinter Datenmember "foo::bar" hinzugefügt.

aber zu dem Fehler steht nirgends etwas. (oder ich kann es in dem Wulst 
von Warnungen nichts sehen.)
Rasputin schrieb:
> Horst schrieb:
>> Rasputin schrieb:
>>> Bei VC++2015 gibt's übrigens keine Warnung.
>> Tu dir selbst einen gefallen und benutz was richtiges zur
>> Programmierung. Die warnen dann auch sinnvoll.
>
> Ich hab bis vor kurzem cygwin mit gcc benutzt. Aber fand es dann albern.
> Entweder richtig Linux in einer VM oder den offiziellen Compiler von
> Microsoft für Windows.

Es gibt ja auch noch mingw. Das versucht nicht gleich, eine komplette 
Un*x-Umgebung unter Windows nachzubilden, sondern bietet einfach eine 
GNU-Toolchain zum bauen von Windows-Programmen.
Gast
Rasputin schrieb:
> Ich hab bis vor kurzem cygwin mit gcc benutzt. Aber fand es dann albern.
> Entweder richtig Linux in einer VM oder den offiziellen Compiler von
> Microsoft für Windows.

[Ziemlich OT]
Ich verfüttere meinen Code regelmäßig sicherheitshalber auch an GCC und 
Clang (und Valgrind und ...). Seit Windows 10 ist das wegen des 
Linux-Subsystems noch einfacher geworden: Den Entwicklermodus aktivieren 
und in Powershell ein Mal
1
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
ausführen, fertig. Ok, in einer VM kann man ohne Fummelei (*) GUIs 
testen etc.

(*)
http://www.howtogeek.com/261575/how-to-run-graphical-linux-desktop-applications-from-windows-10s-bash-shell/

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.