Hallo,
ich habe ein Projekt mit mehreren Files. Ich benötige außerdem eine
Klasse von welcher ich die Memberfunktionen in all meinen .cpp Dateien
nutzen kann.
Es sieht wie folgt aus:
Eine Klasse mit dem Namen meineklasse. Diese ist in der meineklasse.cpp
und meineklasse.h
Nun erstelle ich in main.cpp in der Funktion main eine neue Klasse mit:
meineklasse nummer1(123,123) und übergebe in den Konstruktor zwei
Parameter.
Nun möchte ich aber die Memberfunktionen in der Datei nutzer.cpp
benutzen.
z.B. nummer1.getData();
Jetzt sagt mir aber mein Compiler: error: nummer1 was not declared in
this scope.
Wie kann ich die Klasse nummer1 nun global nutzen? Hat jemand eine Idee?
Grüße
Gleich brüllt ein Experte Singleton. Das ist in 99% der Fälle der erste
Schritt ins Verderben und geschminkter Spaghetti-Code.
Wenn es ohne globale Variablen (Singletons gehören dazu) geht, soll man
es auch ohne erledigen. Das nervt vielleicht am Anfang, erhöht aber die
Chancen, das Programm auch in ZUkunft überblicken und ändern zu können.
Meist der bessere Ansatz:
Wenn Dein Objekt nutzer einen Verweis auf ein Meineklasse-Objekt
braucht, weil es darauf zugreifen muss, bekommt es eine Referenz darauf
im Konstruktor übergeben. Das macht die Abhängigkeit explizit klar.
Wenn alle Objekte kreuz und quer auf alle anderen zugreifen, so dass
diese Methode nicht praktikabel ist, ist der Aufbau des Programmes Mist
und muss sowieso repariert werden.
main.cpp:
Diese Frage ist viel zu unspezifisch. Es gibt verschiedene
Designpatterns die in verschiedenen Situationen angewendet werden
können.
Angenommen, es darf von der Klasse nur eine Instanz geben, dann gibt es
das singleton pattern. Meistens bringt dieses jedoch mehr Probleme als
nutzen.
Wenn das Objekt nicht von anderen Objekten abhängt, und für das gesammte
program relevant ist, bieten sich globale variablen an. Dies kann z.B.
für globale Konfigurationen nützlich sein. Man sollte aber möglichst
wenig davon haben, da man immer auf diese verzichten kann. Der trick ist
hier zu erkennen, was zu welcher Compilationsunit gehört und wieviel
Kapselung man braucht.
Wenn es gleichzeitig mehrere Implementationen eines Objects gibt, und
erst zur Runtime feststeht welche verwendet werden soll, bietet sich das
Factory pattern & interfaces an. Hauffig ist das aber overkill und man
benötigt sowiso nur eine davon, die man einfach direkt dazulinken
könnte.
Das Beispiel von Tom ist eine form von Dependency Injection. Das ist
haufig sinvoll, aber man sollte nicht zuviele davon in einer Klasse
haben.
Welches entwurfsmuster auf deinen Anwendungsfall am besten passt musst
du selbst herausfinden. Achte einfach darauf, dass der code sauber
Strukturiert ist, aber halte ihn möglichst simpel.
Vielleicht habe ich mich etwas unglücklich ausgedrückt ich versuche mal
näher zu beschreiben was ich möchte. Danke trotzdem für die ersten
Antworten.
Ich habe eine main.cpp
1
#include"nutzer.h"
2
#include"meineklasse.h"
3
4
intmain()
5
{
6
MeineKlassenummer1(123,456);
7
nutzerfunktion();//In dieser Funktion sollen nachher Daten der Klasse
8
// "nummer1" genutzt werden
9
10
}
nutzer.h
1
#ifndef NUTZER
2
#define NUTZER
3
voidnutzerfunktion();
4
#endif
nutzer.cpp
1
nutzerfunktion()
2
{
3
inta;
4
5
//blabla ganz viel code...
6
7
//UND NUN!!
8
a=nummer1.getMeAPrivateInt();//hier meckert jetzt der Compiler. Weil ihm die Klasse
9
//nummer1 nicht bekannt ist.
10
11
}
Würde ich jetzt den call
1
MeineKlassenummer1(123,456);
in die nutzer.cpp machen klappt alles, solange sich der Datenaustausch
nur auf die nutzer.cpp beschränkt. Nur wie gesagt, ich möchte die
erstellte Klasse global in meinem Programm nutzen können.
Dann musst du die auch global anlegen.
Allerdings gibt es seit ungefähr Anfang der Zeitrechnung in so ungefähr
allen Programmiersprachen das Konzept der Parameter für Funktionen.
Also definier deine nutzerfuktion mit einem passenden
Referenzparameter...
Oliver
Name schrieb:> Nur wie gesagt, ich möchte die> erstellte Klasse global in meinem Programm nutzen können.
Kannst du doch schon. Oder mainst du die Klasseninstanz/das Objekt
nummer1? Was hindert dich dann daran, dieses Global zu Definieren?
1
main.cpp
2
3
#include"globals.h"
4
#include"nutzer.h"
5
#include"meineklasse.h"
6
7
MeineKlassenummer1(123,456);
8
9
intmain(){
10
nutzerfunktion();//In dieser Funktion sollen nachher Daten der Klasse
11
// "nummer1" genutzt werden
12
}
13
14
globals.h
15
16
externMeineKlassenummer1;
17
18
nutzer.h
19
20
#ifndef NUTZER
21
#define NUTZER
22
voidnutzerfunktion();
23
#endif
24
25
nutzer.cpp
26
27
#include"globals.h"
28
#include"nutzer.h"
29
30
voidnutzerfunktion(){
31
inta;
32
33
//blabla ganz viel code...
34
35
//UND NUN!!
36
a=nummer1.getMeAPrivateInt();//hier meckert jetzt der Compiler. Weil ihm die Klasse
37
//nummer1 nicht bekannt ist.
38
39
}
Ich glaube jedoch nicht, dass du weist, was du wirklich willst.
Ausserdem solltest du mal den Warnlevel auf Maximum und einen Standard
einstellen (unter gcc mit "-Wall -Wextra -pedantic -Werror"), das
fehlende void vor nutzerfunktion ist grauenhafter style, ganz zu
schweigen davon das nutzerfunktion weder eine Klasse noch einen
Namespace hat.
Um noch zu zeigen was Oliver S. vorschlägt:
1
main.cpp
2
3
#include"nutzer.h"
4
#include"meineklasse.h"
5
6
intmain(){
7
MeineKlassenummer1(123,456);
8
nutzerfunktion(nummer1);//In dieser Funktion sollen nachher Daten der Klasse
9
// "nummer1" genutzt werden
10
}
11
12
nutzer.h
13
14
#ifndef NUTZER
15
#define NUTZER
16
voidnutzerfunktion(MeineKlasse&);
17
#endif
18
19
nutzer.cpp
20
21
#include"nutzer.h"
22
23
voidnutzerfunktion(MeineKlasse&nummer1){
24
inta;
25
26
//blabla ganz viel code...
27
28
//UND NUN!!
29
a=nummer1.getMeAPrivateInt();//hier meckert jetzt der Compiler. Weil ihm die Klasse
Ich glaube hier ist der Spruch "Kauf dir ein (gutes) C++ Buch."*
wirklich angebracht.
*Ein gutes C-Buch wuerde hier auch weiterhelfen um zu verstehen was man
ueberhaupt tut.
Daniel A. schrieb:> Ich glaube jedoch nicht, dass du weist, was du wirklich willst.
Doch.
Daniel A. schrieb:> Ausserdem solltest du mal den Warnlevel auf Maximum und einen Standard> einstellen (unter gcc mit "-Wall -Wextra -pedantic -Werror"), das> fehlende void vor nutzerfunktion ist grauenhafter style, ganz zu> schweigen davon das nutzerfunktion weder eine Klasse noch einen> Namespace hat.
Mein Code ist ja auch nur ein bsp. natürlich fehlen da noch tausend
Dinge. Es ging hier nur darum mal schematisch darzustellen was mein
Problem ist.
Es hilft auch nicht wenn ich den call:
1
MeineKlassenummer1(123,456);
vor die "main" setze. So wie du es hier vorgeschlagen hast.
1
main.cpp
2
3
#include"globals.h"
4
#include"nutzer.h"
5
#include"meineklasse.h"
6
7
MeineKlassenummer1(123,456);
8
9
intmain(){
10
nutzerfunktion();//In dieser Funktion sollen nachher Daten der Klasse
11
// "nummer1" genutzt werden
12
}
Mir geht es nur darum, dass mein Programm mittlerweile viele Dateien
hat. Ich habe eine Klasse erstellt in welcher Kerninformationen von
jedem Sensor gespeichert werden. Mit jedem:
1
MeineKlassenummer1(123,456);
1
MeineKlassenummer2(123,456);
1
MeineKlassenummer3(123,456);
Erzeuge ich einen Sensor. NUN möchte ich aber egal wo in meinem Programm
die Möglichkeit haben diese Daten zu ändern. Dafür habe ich die
Sensordaten private gesetzt und mir Funktionen geschrieben, mit denen
ich diese nach Bedarf ändern kann.
Alle anderen Funktionen wie z.B. die "nutzerfunktion" werden egal wo in
meinem Programm, erkannt. Ich habe nur das problem mit der Klasse. Es
ist mir irgendwo nicht möglich außerhalb der Main, memberfunktionen der
Klasse zu nutzen. Ich kann diese NUR!!! da nutzen, wo ich auch
tatsächlich den call:
main.cpp
...
...
1
MeineKlassenummer1(123,456);
...
...
gemacht habe.
Jetzt wäre es mir möglich in der main.cpp z.B. diese Funktion zu nutzen:
nummer1.gebeDenBlödenTextAus();
In jeder anderen Datei ist es mir aber nicht möglich nun diese Fkt. zu
nutzen. Ich verstehe aber nicht warum. Mit normalen Funktionen geht es,
sobald man den "header" anfügt. Mit der Klasse aber nicht.
Name schrieb:> In jeder anderen Datei ist es mir aber nicht möglich nun diese Fkt. zu> nutzen. Ich verstehe aber nicht warum. Mit normalen Funktionen geht es,> sobald man den "header" anfügt. Mit der Klasse aber nicht.
Die Klasse ist ja keine Funktion. Das ist eine Variable! Auf die
könntest du auch nicht zugreifen. Außer: du gibst die bekannt... (Ich
schreibe jetzt mal nicht, dass man dazu 'extern' verwendet.)