C++ rekursiv auf eine Klasse zeigen

Gast #5418820
Lesenswert?

Hallo ihr,

ich habe mein Problemchen mal vereinfacht. Ich möchte in der Klasse1, 
viele Objekte von Typ Klasse2 haben, die ihrerseits jeweils auf ein 
Objekt der Klasse1 zeigen. Klasse2 ist quasi ein Knoten könnte man sagen 
(der noch weitere Eigenschaften und Methoden haben soll).

Zur Vereinfachung des Problems, hier nur eine Klasse1 in Klasse2 die 
einen Zeiger auf Klasse1 behinhaltet:
1
#include "Klasse2.h"
2
class Klasse1
3
{
4
  Klasse2 k2;
5
public:
6
  Klasse1();
7
  ~Klasse1();
8
};
1
class Klasse2
2
{
3
  Klasse1* k1;
4
public:
5
  Klasse2();
6
  ~Klasse2();
7
};

Nur leider schmeckt das dem Kompiler nicht. Er kommt mir mit 
Fehlermeldungen wie
* Es fehlt ";" vor "*"
* Unerwartetes Token vor ";"
* Fehlender Typspezifizierer - int wird angenommen

Ist das Problem, dass #include "Klasse2.h" VOR der Deklaration der 
Klasse1 steht und er die Klasse1 noch nicht kennt wenn er die Klasse2 
und somit den Zeiger auf die Klasse1 deklarieren soll? Aber die Klasse1 
in der Klasse2 ebenfalls zu includieren wäre ja noch unsinniger, dann 
beißt sich die Katze ja in den Schwanz.

Weshalb geht das so nicht? Er soll ja lediglich eine Speicheradresse 
speichern in k1...

Bevor ich jetzt irgendein schreckliches Konstrukt aufziehe, könnt ihr 
mir bitte sagen, wie man sowas richtig macht?

Danke!
#5418832
Lesenswert?

Wüli schrieb:
> Ist das Problem, dass #include "Klasse2.h" VOR der Deklaration der
> Klasse1 steht und er die Klasse1 noch nicht kennt wenn er die Klasse2
> und somit den Zeiger auf die Klasse1 deklarieren soll?

Genau das. Man kann das ganze durch eine Forward Declaration umgehen. 
Mit der Forward Declaration kannst du dann Pointer auf deine Klasse 
anlegen. Sobald du dann aber auf irgendwelche Member der Klasse 
zugreifen willst brauchst du die volle Deklaration. In der Klasse2.cpp 
wirst du dann vermutlich doch Klasse1.h inkludieren, was an dieser 
Stelle aber nicht mehr zu Problemen führt.
Gast #5419174
Lesenswert?

Sebastian V. schrieb:
> Genau das. Man kann das ganze durch eine Forward Declaration umgehen.

Mmmhhh, das ist aber nicht die OOP Lösung.
Was passiert, wenn du 'Klasse1' überarbeitest, als Ableitung? Dann musst 
du 'Klasse2' auch ändern.

Bei OOP gibt es die späte Bindung: Polymorphie!

https://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Polymorphie
http://openbook.rheinwerk-verlag.de/oop/oop_kapitel_05_002.htm
Gast #5419191
Lesenswert?

"OOP 4 all" hat recht. Da das Thema Polymorphie erst mal etwas abstrakt 
ist sollte der TO vieleicht mal konkreter sagen was er will.
Warum hat er diese zyklische Abhängigkeit von jeder Klasse zur jeweils 
anderen?
Ziemlich wahrscheinlich gibt es eine deutlich elegantere Methode dieses 
Problem zu lösen.
Gast #5419858
Lesenswert?

Ich möchte ein >einfaches< neuronales Netz programmieren. Gleich mal 
vorweg, noch versteh ich nicht allzuviel von dem Thema, hab nur die 
ersten paar Seiten eines Buches darüber gelesen. Trotzdem wollte ich 
direkt parallel dazu schon ein wenig experimentieren und dabei meine 
C++-/Softwareengeneeringkentnisse auffrischen (ist ne Weile her). 
Entsprechend gespannt bin ich darauf, wie ihr meint, wie man das 
ordentlich OOP-konform lösen sollte.

Die Klasse1 ist ein Unit bzw. Neuron. Die Klasse2 ist die Verbindung zu 
einem anderen Unit. Ich nenne die Klasse2 LineOut. Lineout enthält einen 
Zeiger auf Unit-Objekt sowie die Gewichtung der Verbindung. Die 
hauptsächlichen Methoden der LineOut-Klasse sind fire()(stimuliert das 
Unit, auf das der Zeiger zeigt) und setWeight(int)(verändert die 
Gewichtung der Verbindung). Ein Objekt der Klasse1, also ein 
Unit-Objekt, kennt mehrere Lineout-Objekte, weil ein Unit mit mehreren 
anderen Units verbunden ist.

Die wichtigste Eigenschaft der Unit-Klasse ist der Schwellenwert. Wenn 
die Summe der Gewichtungen aller LineOut-Objekte die ein Unit 
stimulieren größer ist als dieser Schwellenwert, stimuliert dieses Unit 
seinerseits alle seine LineOut-Objekte, die dann die Units stimulieren, 
auf die sie zeigen.

Sollte das Ergebnis, dass das Netz liefert, richtig sein, sollen die die 
Gewichtungen erhöht werden, die erfolgreich Units stimuliert haben. Ist 
das Ergebnis falsch, werden sie verringert.

Vielleicht hat dieses Konzept den Namen neuronales Netz noch nicht 
verdient, trotzdem geht es in die Richtung und ihr wisst, worauf ich 
hinaus will.


Sollte ein Unit-Objekt seine LineOut-Objekte vielleicht nicht selber 
erzeugen? Oder sollte die Verbindung zwischen Units nicht mit einer 
separaten Klasse gelöst sein?

Bin gespannt!
Gast #5419871
Lesenswert?

...ergänzend dazu...
1
class Neuron
2
{
3
private:
4
  vector<LineOut*> out;
5
  int schwelle;
6
  int accu;
7
  void fireOut();
8
  
9
public:
10
  void addLineOut(Neuron*, int);
11
  void setSchwelle(int);
12
  void fireIn(int);
13
  Neuron();
14
  ~Neuron();
15
};
1
class LineOut : public Line
2
{
3
private:
4
  int weight;
5
  Neuron *unit;
6

7
public:
8
  void fire(int);
9
  void good();
10
  void bad();
11
  void setWeight(int);
12
  int getWeight();
13
  LineOut();
14
  ~LineOut();
15
};
Gast #5422227
Lesenswert?

Ich weiß nicht, was du unter
>C++-/Softwareengeneeringkentnisse
verstehst. Das kann von Person zu Person variieren. Sind dir "Design 
Pattern" bekannt?

> Das Buch zu dem Thema
ist das eines speziell über Neuronale Netzwerke, oder eines im Sinne von 
"Neuronale Netzwerke unter C++"?

Von der Herangehensweise würde ich mir an deiner Stelle überlegen, was 
deine Neuronen und Verbindungen zu einander ausmacht - hast du ja schon.
Dann Design Patterns durchwühlen und schauen, welches deiner 
Aufgabenstellung am nächsten kommt.
Oder du googlest, ob es verbreitete Pattern für neuronale Netzwerke 
gibt.
Könnte in die Richtung Composite Pattern gehen.

https://www.tutorialspoint.com/design_pattern/composite_pattern.htm
Gast #5422243
Lesenswert?

Duck Mc Scrooge schrieb:
> Könnte in die Richtung Composite Pattern gehen.
>
> https://www.tutorialspoint.com/design_pattern/composite_pattern.htm

Das gleift hier zu kurz, weil da (siehe Beispiel in dem Link von dir) 
ein "Empoyee" einfach eine Liste von Empoyees hat.
Er muss aber da eine Klasse für die Verbindung definieren, die intern 
noch mindestens eine Eigenschaft hat.
Insofern sehe ich ad hoc keine einfachere Lösung als die vom TO 
angedachte:

Neuron hat eine Liste von Verbindungen
Jede Verbindung hat wieder ein Neuron als Ziel und mindestens eine 
Gewichtung als Attribut.

Also wohl forward Deklaration, aber vieleicht hat noch jemand anderes 
eine bessere Idee
Gast #5424991
Lesenswert?

Ich sag ja, es könnte in die "Richtung" gehen.
Wenn man die Employe Klasse nach einem Interface (DISCLAIMER) 
implementiert, wird das ganze schon deutlich flexibler. Dann kann man 
verschiedene Klassentypen, welche das Interface implementieren 
ineinander schachteln.

Das riecht ein bisschen nach Baum oder Graph.
Gast #5437886
Lesenswert?

Das ist wohl der springende Punkt, mit dem Composite Pattern baut man 
eine Klasse, wo eine Instanz die auf eine ANDERE Instanz des SELBEN Typs 
zeigt, nicht aber auf sich selbst. Was sollte das auch bewirken?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren