Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Chase

Alter Hase

  • »Chase« ist der Autor dieses Themas

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

31

13.07.2006, 01:29

Dass der Base-Ctor die falsche Fkt. aufruft war mir fast klar, ich wollts nur noch mal von euch hoeren.
Weiter gehts mit meinen Fragen: (danke uebrigens fuer eure hilfe)
Darf ich in einem Construktor mit Parametern einfach so den Standart-C'tor aufrufen?
"Have you tried turning it off and on again?"

32

13.07.2006, 07:53

in der initialisierungsliste, ja

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

33

13.07.2006, 12:35

Zitat von »"Chase"«


Tja gegen Container hab ich in diesem Fall auch was einzuwenden:
So wie das jetzt geschrieben ist kann ich 'liste' schlecht kopieren: Die Zeiger werden zwar alle kopiert, zeigen jedoch immernoch auf die selben Objekte.


Ich frage mich, wo da der Unterschied zu deiner Implementation ist. Du kopierst doch auch nur die Zeiger, nachdem du das Feld vergrößert hast. Wenn ich ein neues Objekt in meine Liste speichern will, schreibe ich einfach

C-/C++-Quelltext

1
liste.push_back (neues_objekt);
und gut ist. Dabei überlasse ich es der Liste, sich selbst zu vergrößern und muss das nicht umständlich selbst machen.

Zitat von »"Chase"«

Der Konstruktor der Basisklasse soll eine virtuelle Memberfunktion aufrufen, die natuerlich die entsprechene Fkt. der Subklasse sein soll. Geht das irgendwie?


Klar geht das, wenn man weiss, was man tut.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class FooBase
{
  FooBase ()
  {
    foo ();
  }
  virtual void foo () = 0;
};

class Foo : public FooBase
{
  Foo ()
    : FooBase ()
  {
  }

  virtual void foo ();
};

int main ()
{
  new FooBase (); // Compiler-Fehler, weil foo () abstrakt

  new Foo (); // Erzeugt ein Foo-Objekt und Foo::foo () wird im FooBase Konstruktor benutzt

}

Wäre Foo::foo () nicht abstrakt, würden beide Objekte erzeugt, nur dass im ersten Fall eben FooBase::foo () benutzt wird.

Fazit: Es gibt keine "virtuellen Konstruktoren," weil bei Erzeugung von Objekten bekannt sein muss, welchen Typ sie haben.

Zitat von »"Nox"«

Jedoch dürfen dafür die zu überladene Funktione nicht inline sein. Das hier wird also nicht korrekt funktionieren:

virtual void sprich(void){out("foo!");} <- Da inline nicht korrekt überladbar


Falsch. Man kann generell jede Methode überladen, egal ob sie nun inline ist, oder nicht. inline ist nur eine Hilfe für den Compiler, dass es wünschenswert ist, für die Methode keinen Aufruf zu generieren, sondern den Quelltext an der benutzten Stelle einzubetten. Der Compiler muss das aber nicht so machen. Virtuelle Methoden werden so gut wie niemals inline expandiert.

MfG
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

34

13.07.2006, 14:26

Right, das Problem, was ich hatte tratt auf Grund eines anderen Fehlers auf, wie ich in nach hinein festgestellt habe. Es sah daher so aus, als ob die Methode nicht überladen wurde. Mein Fehler.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

35

13.07.2006, 14:41

Zitat von »"rklaffehn"«


Klar geht das, wenn man weiss, was man tut.

error LNK2019: unresolved external symbol "public: virtual void __thiscall FooBase::foo(void)" (?foo@FooBase@@UAEXXZ) referenced in function "public: __thiscall FooBase::FooBase(void)" (??0FooBase@@QAE@XZ) main.obj

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

36

13.07.2006, 16:32

Zitat von »"WarMuuh!!"«

Zitat von »"rklaffehn"«


Klar geht das, wenn man weiss, was man tut.

error LNK2019: unresolved external symbol "public: virtual void __thiscall FooBase::foo(void)" (?foo@FooBase@@UAEXXZ) referenced in function "public: __thiscall FooBase::FooBase(void)" (??0FooBase@@QAE@XZ) main.obj


Wenn du das ausprobieren willst, solltest du dir wenigstens eine Implementation von Foo::foo () ausdenken, die ich nämlich weggelassen habe. (ist für das Beispiel nicht wichtig) Dann kann man das nämlich auch linken (!= compilieren).

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

37

13.07.2006, 17:12

arg...wiso wusste ich, das diese antwort kommt...
ganz blöd bin ich nich...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class FooBase
{
public:
  FooBase ()
  {
    foo ();
  }
  virtual void foo () = 0;
};

class Foo : public FooBase
{
public:
  Foo ()
    : FooBase ()
  {
     
  }

  void foo ();
};


void Foo::foo()
{
    cout << "foo";
}

int main ()
{
  Foo* f = new Foo (); // Erzeugt ein Foo-Objekt und Foo::foo () wird im FooBase Konstruktor benutzt

  delete f;

}


EDIT
so, hab ma was kleines zusammengewurschtelt, das kompilieren tut und wo man ungefähr sehen kann, warum das nich funktioniert...
wer bock hat, kann es sich ja mal anguggen.
allerdings hab ich s mit VC2005 gemacht...da kann man halt in die _vftable reinguggen, weiß nich, obs in anderen versionen auch geht

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

38

13.07.2006, 17:35

Sorry, hätte ich auch selbst am Linker-Fehler sehen können.

Da falle ich aber auch jedes Mal drauf rein. Abstrakte Methoden in einem Konstruktor gehen nicht! Gemeiner sind nicht abstrakte Methoden, die dann aber nicht so aufgerufen werden, wie man das gerne hätte; nur der Linker meckert nicht mehr.

Warum das so sein muss, will mir aber eben nicht einfallen, da muss ich nochmal nach der Antwort suchen. 8)

MfG
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

39

13.07.2006, 18:24

Zitat von »"rklaffehn"«


Warum das so sein muss, will mir aber eben nicht einfallen, da muss ich nochmal nach der Antwort suchen. 8)


naja, genau kann ichs halt auchnich sagen, ich denk mal, das die konstruktoren ja im zwiebelschalensystem aufgerufen werden, und jeder konstruktor hat halt bloß die vft der aktuellen klasse zur verfügung ...
erst, wenn der constructor der abgeleiteten klasse beginnt (nach der init-liste), stehen die richtigen einträge in der vft...soweit kann man das halt in meinem beispiel mitbekommen...

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

40

13.07.2006, 18:40

Es ist mir wieder eingefallen. Man stelle sich folgendes Konstrukt vor:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class A
{
public:

  A ()
  {
    foo (); // Bedeutet A::foo (), gibts ist aber nicht implementiert.

  }

  virtual void foo () = 0;
};

class B : public A
{
public:

  B () : A (), _ptr (new int (0))
  {
  }

  void foo ()
  {
    *_ptr = 1;
  }

private:

  int* _ptr;
};


Wenn B::foo () im Konstruktor von A aufgerufen würde, wäre B::_ptr noch gar nicht initialisiert. Damit kann ich dort höchstens A::foo () aufrufen, was es aber nicht gibt, da es pur virtuell ist.

Damit hier keiner auf die Idee kommt, einfach die Reihenfolge der Initialisierungen zu tauschen: die Initialisierung der Basisklasse muss immer als erstes passieren, weil ich im Konstruktor von B sehrwohl immer auf Elemente von A zugreifen darf, auch schon in der Initialisierungs-Liste (das zwischen ':' und '{').

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige