# C++ Klasse in einer Klasse, Deklarationsfehler



## 10rotator01 (12. Mai 2013)

Hallo Leute,

ich habe folgendes Problem. Ich habe ein Klasse geschrieben, die ich innerhalb anderer Klassen verwenden möchte.
Soweit so gut, es erkennt auch die Klasse, aber beim Kompilieren meint der Compiler, das einiges nicht deklariert sei:

Also:
Header 1:

```
#pragma once
class point
{
private:
    int pos_x;
    int pos_y;

public:
    point();
    point(int x, int y);
	void setCoordinates(int x, int y);
};
```

CPP 1:

```
#include "point.hpp"


point::point(void)
{
	pos_x = 0;
    pos_y = 0;
}

point::point(int x, int y)
{
	pos_x = x;
    pos_y = y;
}
void point::setCoordinates(int x, int y)
{
	pos_x = x;
	pos_y = y;
}
```

Header 2:

```
#pragma once
class rob
{
private:
	point *pos;

public:
	rob(int x, int y);
	void moveTo(int x, int y);
};
```

CPP 2:

```
#include "rob.hpp"
#include "point.hpp"


rob::rob(int x, int y)
{
	pos = new point(x, y);
}

void rob::moveTo(int x, int y)
{
	pos->setCoordinates(x, y);
}
```

Der Compiler spuckt mir folgendes aus: 
Fehler	3	error C2065: 'pos': nichtdeklarierter Bezeichner	f:\programmierung\c++\labrob1\labrob1\rob.cpp	7	1	labrob1
Und verweist mir auf die beiden pos im CPP2.

Ich habe jetzt schon eine Weile probiert, aber ich komme nicht mehr weiter.
Mein Problem wäre auch gelöst, wenn mir jemand sagen könnte, ob es in C++ die vordefinierte Klasse Point gibt wie in C#.
hab danach gegoogelt, aber nichts gefunden.

lg,
10rotator01

Nachtrag:
ok, habe meinen Fehler jetzt doch gefunden...
Ich war so schlau und habe die Headerfiles in der falschen Reihenfolge inkludiert...


----------



## sheel (12. Mai 2013)

Hi

warum machst du kein include "point.hpp" in der rob.hpp?

So auf die Reihenfolge achten zu müssen macht schwer änderbaren Code.


----------



## 10rotator01 (12. Mai 2013)

Hi,

ich weißt nicht wo, aber ich hab mal gelesen, bei Klassen sollte man die includes in der cpp halten, weiß aber auch nicht mehr warum...

Inwiefern macht das einen Unterschied? 

lg


----------



## cwriter (12. Mai 2013)

Hö? Man inkludiert in den .cpp-Dateien die zugehörigen .h(pp)-Dateien, in den .h(pp)-Dateien werden die Header für die .cpp-Datei inkludiert. Zumindest mache ich das so.

Beispiel:

```
//a.hpp
#ifndef A_H
#define A_H
#include <stdio.h>
//usw.

class a
{
    //blabla
};
#endif


//a.cpp

#include "a.hpp"

a::a()
{

}
//blabla
```

Gruss
cwriter

//EDIT: Ja, lese ich auch immer wieder. Ich verstehe aber nicht, warum. Meist muss man ja für die Typdefinitionen sowieso ein paar Header in der Headerdatei inkludieren, da ist es m.M.n. einfacher, einfach alles in eine Datei zu schreiben.
Unterschied macht es - bis auf einige wenige Fälle - keinen.


----------



## sheel (12. Mai 2013)

Technisch gesehen machts überhaupt keinen Unterschied.
Aber in einem Projekt mit, Hausnummer, 100 Codedateien wird man froh sein,
nicht jedesmal die Reihenfolge überlegen zu müssen.

Verarbeitet muss die point.hpp sowieo werden, egal ob es wegen der rob.hpp oder rob.cpp ist.
Man spart dem Compiler dadurch auch nichts.
Und falls die Datei zweimal inkludiert ist: Dafür ist dann das pragma-once
Verhindert mehrmalige Abarbeitung; bzw. der Compiler merkt sich, welche Dateien er schon hat.

edit:
Gibt natürlich verschiedene Meinungen dazu, wie zu so vielen Sachen im Programmierbereich.
Persönliche Vorgehensweise: Eine Headerdatei überall dort inkludieren,
wo etwas aus dieser Headerdatei verwendet wird.
Überall = Egal ob Cpp, hpp...


----------



## cwriter (12. Mai 2013)

@sheel
#pragma once ist aber nur für VS, oder?


----------



## sheel (12. Mai 2013)

Unabhängiger wäre die ifndef-define-Variante.

edit: Nein, geht auf mehreren.
http://en.wikipedia.org/wiki/Pragma_once


----------



## 10rotator01 (12. Mai 2013)

Super! Danke für die ausführliche Beschreibung.
Hat mir sehr viel geholfen. 

lg


----------



## MCoder (13. Mai 2013)

Hallo 10rotator01,

da du in deinem Header 2 die point-Klasse als Zeiger verwendet hast, würde auch eine sogenannte Vorwärtsdeklaration der point-Klasse reichen und du kannst das Include in der cpp belassen.

```
#pragma once

class point; // Vorwaertsdeklaration

class rob
{
private:
    point *pos;
 
public:
    rob(int x, int y);
    void moveTo(int x, int y);
};
```
Gruß
MCoder


----------



## Der Wolf (13. Mai 2013)

Hallo,

ich denke die Sache mit "... bei Klassen sollte man die includes in der cpp halten ... " macht am meisten Sinn, bei nicht-open source Projekten wo nur so wenig an Klassen-Layout preisgegeben werden soll wie möglich. Dann muss man Header-Dateien nicht mit raus geben, wenn sie nur von internen Klassen includiert werden die zum Beispiel in einer ausgelieferten Library liegen. Dann kann man auch die Übersicht für Kunden erleichtern und bläht auch die API Dokumentation (falls es eine gibt) nicht mit Funktionen/Methoden etc. auf, auf die der Kunde eigentlich eh keinen Zugriff haben sollte.

Gruß,
Der Wolf


----------



## cwriter (13. Mai 2013)

Bei Closed-Source müsste ja gerade der Code (.cpp) geschützt bleiben, da wäre mir die Klassendefinition eher egal.
Oder wie meinst du das?

Gruss
cwriter


----------



## Der Wolf (14. Mai 2013)

Nein, da hast du schon recht. In der Regel sind die Klassendefinitionen auch egal. Aber ich persönlich finde es auch schön, falls die Auslieferung in einer Library geschieht auch nur die Header mit ausgeliefert werden, die wirklich gebraucht werden und interne Klassendefinitionen auch nur in internen Headern verwaltet werden. Das ist einfach übersichtlicher. 

Ganz allgemein hast du aber Recht, cwriter: Die Sourcen sind das was geschützt werden muss. Das Klassen-Layout nicht unbedingt.

Gruß,
Wolf


----------

