moin,
ich habe mal eine Frage bezüglich statsicher Methoden:
Ich bearbeite einen Teil einen relativ großen Projektes, genauer der
Teil ist schon fertig ich soll ihn "nur" beschleunigen...
Meine Arbeit ist für's erste auch nur auf eine Klasse beschränkt. In
dieser Klasse werden u.a. 3 private Funktionen als statisch deklariert,
nun brauch ich 2 variablen die innerhalb der gesamten Klasse von den
Methoden benutzt werden können, kein problem einfach fix 2 private Class
member deklariert...problem: eigentlich benutzen nur die 3 statischen
methoden diese Variablen --> ich bekomme eine Fehlermeldung beim
kompilieren das die class member static sein müssen sonst könne sie in
den statischen Methoden nicht verwendet werden. Wenn ich die Variablen
jedoch als statisch deklariere bekomme ich beim compilieren eine
Fehlermeldung beim Linken in der Art "Symbole ... können nicht gefunden
werden" (ich benutze Visual C++)
Wenn ich die 3 methoden ganz normal deklariere (also einfach das static
weglasse) und die variablen auch ganz normal deklariere bekomme ich
keine Fehlermeldung, der Code kann kompiliert werden und das ganze
Programm läuft auch einwandfrei...
Da ich allerdings keinen Überblick über den Code des ganzen Projektes
habe würde ich ungern einfach die Methodendeklaration quasi veränder, da
der ursprüngliche Programmierer sich sicherlich etwas dabei gedacht hat
die Funktionen als static zu deklarieren.
Hat jemand eine Idee warum ich diese Fehlermeldung bekomme?bzw. kann mir
jemand sagen wie ich's richtig machen könnte?
Ich selbst arbeite jetzt das erste mal mit C++ und bin mit der
Objektorientierten Programmierung noch nicht so vertraut...im Studium
hatte ich auch bisher nur C...
Gruß Flutsch
Flutsch1987 schrieb:> methoden diese Variablen --> ich bekomme eine Fehlermeldung beim> kompilieren das die class member static sein müssen sonst könne sie in> den statischen Methoden nicht verwendet werden.
Yep, ohne instance gibt es nur die statics.
> Wenn ich die Variablen> jedoch als statisch deklariere bekomme ich beim compilieren eine> Fehlermeldung beim Linken in der Art "Symbole ... können nicht gefunden> werden" (ich benutze Visual C++)
Die müssen irgendwo mal definiert werden, ähnlich wie globale Variablen
in C.
Flutsch1987 schrieb:> Wenn ich die 3 methoden ganz normal deklariere (also einfach das static> weglasse) und die variablen auch ganz normal deklariere bekomme ich> keine Fehlermeldung, der Code kann kompiliert werden und das ganze> Programm läuft auch einwandfrei...
Damit hast du aber auch eine ganz andere Funktionalität!
Ohne static hat jedes Objekt einen eigenen Satz dieser Variablen.
Und jeder dieser Sätze kann einen anderen Wert haben.
Ist es das, was du willst?
@Klaus
genau soetwas habe ich mir schon gedacht...die fuktionalität will ich
eigtl. nicht ändern, weil ich gar nicht weiß wo und wie genau in der
Impementation Objekte von der Klasse generiert werden...wie gesagt
bearbeite bisher wirklich nur nen sehr kleinen teil des projektes...
@A.K.
A. K. schrieb:> Yep, ohne instance gibt es nur die statics.
das versteh ich gerade gar nicht was du mir damit sagen willst..
A. K. schrieb:> Die müssen irgendwo mal definiert werden, ähnlich wie globale Variablen> in C.
hm,
deklariert werden sie in dem fall im header file und definert werden sie
doch automatisch sobald ich ihnen das erste mal nen wert zuweise, oder
versteh ich da gerade was falsch?
deklariert ==> Compiler kennt den namen der variable
definiert ==> der variablen wird nen Speicherbereich zugewiesen
Der compiler muss Wissen in welchee Objektdatei der Speicher für die
Variable angelegt werden soll. (Stichwort "One Definition Rule", siehe
http://en.wikipedia.org/wiki/One_Definition_Rule). Die statische
Variable muss genau in einer Übersetzungseinheit vorhanden sein. Dafür
muss der compiler wissen in welcher er diese Variablen anlegen soll. In
dem Wikipedia artikel ist ein Beispiel für statische variablen.
Compiler verhalten sich hier unterschiedlich. gcc und soweit ich weiß
auch msvc2008 können statische Variablen in der Klassendeklararion
direkt Verarbeiten. Es gelten dann die gleichen Regeln wie bei in der
header datei definierten Funktionen. Msvc2005 z.B. kann dies nicht. Dann
müssen die statischen Memeber in einer .c explizit angelegt werden.
Flutsch1987 schrieb:> A. K. schrieb:>> Yep, ohne instance gibt es nur die statics.>> das versteh ich gerade gar nicht was du mir damit sagen willst.
Eine "normale" Membervariable existiert einmal pro Objekt.
Hat also eine Klasse A die Member i und j, dann gibt es
bei 10 Objekten der Klasse auch 10 i und 10 j.
Die static-Member einer Klasse dagegen exisiteren ab
Programmstart jeweils genau einmal - ganz egal, ob
und wieviel Objekte der Klasse es gerade gibt.
Jedes existierende Objekt ist eine Instanziierung oder
instance der Klasse.
Genau deshalb dürfen static-Methoden einer nur auf
static-Member der Klasse zugreifen, im Gegenzug aber dafür
auch aufgerufen werden, ohne daß es ein Objekt geben muß.
Normale Methode (nicht-static) können dagegen nur für ein
bestimmtes Objekt der Klasse aufgerufen werden und dürfen
damit auch die nicht-static-Member anfassen.
Ohne dieses Verständnis ist es relativ sinnlos, damit zu
programmieren...
Flutsch1987 schrieb:> A. K. schrieb:>> Yep, ohne instance gibt es nur die statics.>> das versteh ich gerade gar nicht was du mir damit sagen willst..
Eine als static declarierte Methode ist ohne Objekt von der Klasse
aufrufbar:
1
classTest{
2
public:
3
staticvoidtest(){}
4
};
5
6
voidmain(){
7
Test::test();
8
}
Es gilt als schlechter Programmierstil, wenn man die Methode wie eine
Methode von einem Objekt aufruft und nicht wie oben geschrieben
Test::test() (bei Java Eclipse geht sowas auch und wird dann als Warnung
angezeigt).
static-Variablen gehen auch, ebenfalls mit der class::-Syntax, aber dir
muß dann auch klar sein, daß für alle Objekte derselbe Wert gilt, so als
hättest du nur eine globale normale C-Variable angelegt. Ist
normalerweise kein guter Programmierstil, man verwendet für sowas meist
das Singleton-Entwurfsmuster, aber kommt ganz auf deinen Anwendungsfall
drauf an.
Flutsch1987 schrieb:> deklariert ==> Compiler kennt den namen der variable> definiert ==> der variablen wird nen Speicherbereich zugewiesen
Eben. In C:
extern int var; // Deklaration
int var = 1; // Definition mit Initialisierung
In C++:
class C { static int var; }; // Deklaration
int C::var = 1; // Definition mit Initialisierung
Und letzteres fehlt bei dir.
@ Klaus
ok, soweit hab ich's verstanden..
ich muss mir am montag den code nochmal genauer anschauen, aber ich
denke das Mittel der Wahl wird dann sein die Methoden weiterhin als
static deklariert zu lassen, die Variablen ebenfalls als static zu
deklarieren und mir nochmal gedanken über deren definition mache...und
mir mal genauer anschauen warum diese Methoden als static deklariert
wurden..
also,
ich hab mir den Code gerade nochmal angeguggt und mir ist folgendes
aufgefallen:
Die statische Methode ( ich beschränke mich jetzt mal auf die oberste im
Funktionsbaum, die anderen beiden werden nur von dieser aufgerufen )
wird wiederum nur von einer privaten nicht statischen Methode der selben
Klasse aufgerufen, d.h. es existiert ja sowieso ein Objekt der Klasse
wenn die statische Funktion aufgerufen wird. Ist es da nicht sinnlos die
Methode noch als statisch zu deklarieren?
Soweit ich das verstanden hab ist ja der Vorteil von statischen Methoden
das ich auch auf sie zugreifen kann ohne ein Objekt der Klasse erstellt
zu haben...
hoffe meine ausfühungen sind nicht allzu konfus :D
Gruß
Flutsch
Technisch gesehen ist es dann erstmal egal, ob die Methode auch
als static deklariert ist (bei den Variablen dagegen ist der
Unterschied nach wie vor enorm!).
Nichtsdestotrotz macht es Sinn, die Methode als static zu
deklarieren. Dann weiß der geneigte Leser des Quelltextes
bzw. der Programmierer um das Verhalten der Methode, nämlich
daß sie nicht auf einem (bzw. dem aktuellen *this) Objekt
arbeitet.
Zudem kann der Compiler evtl. besseren Code erzeugen, wenn er
das ebenfalls weiß.
Schaden tut es sicher nicht, also lieber klar und deutlich
programmieren.
hm,
das klingt einleuchtend, mein Problem ist aber das die 3 statischen
Methoden alle auf die gleichen variablen zugreifen sollen und sie ggf
verändern...wenn ich's mir gerade recht überlege wäre es ja dann am
sinnvollsten die variablen als static zu definieren ( die variablen habe
sowieso ich eingeführt, also im "Ursprungscode" sind sie nicht
enthalten..), da methoden eh unabhängig vom objekt arbeiten...
Flutsch1987 schrieb:> Die statische Methode ( ich beschränke mich jetzt mal auf die oberste im> Funktionsbaum, die anderen beiden werden nur von dieser aufgerufen )> wird wiederum nur von einer privaten nicht statischen Methode der selben> Klasse aufgerufen, d.h. es existiert ja sowieso ein Objekt der Klasse> wenn die statische Funktion aufgerufen wird.
Wenn deine Variablen nur von den 3 statischen Methoden benutzt wird, und
die beiden statischen Methoden nur von einer dritten aufgerufen werden,
warum machst Du dann überhaupt eine zur Klasse hin globale Variable?
Definiere sie in der ersten Funktion und übergebe eine Referenz den
beiden aufgerufenen Methoden.
Ausserdem solltest Du dir mal das Pattern (Entwurfsmuster) Singelton
reinziehen.
Allgemein: Source Code anhängen hilft denen, die dir helfen sollen,
weniger im Trüben zu fischen.
grtz,
da haste natürlich recht bei all dem neuen hab ich an die guten alten
pointer nicht gedacht...
naja, aber dümmer geworden bin ich auch nicht :D
Und zum Source Code, den darf ich nicht anhängen weil er nicht
öffentlich ist..
U.R. Schmitt schrieb:> Wenn deine Variablen nur von den 3 statischen Methoden benutzt wird, und> die beiden statischen Methoden nur von einer dritten aufgerufen werden,> warum machst Du dann überhaupt eine zur Klasse hin globale Variable?> Definiere sie in der ersten Funktion und übergebe eine Referenz den> beiden aufgerufenen Methoden.
Ich stimme zu,, das hört sich so doch recht abenteuerlich an, (statisch)
Member sind nicht geeignet als "Variable" zwischen Funktionen verwendet
zu werden, da dann das Ergebnis ggf. von der Reihenfolge der Aufrufe der
Funktionen abhängt.
Außerdem kann (theoretisch) jeder zu jederzeit die Variable ändern (z.B.
bei einem Mulithreadzugriff) würde das deinen Funktionen "gefallen"?
Wenn die Varable ihren Wert zwischen den Aufrufen halten soll, so kann
diese Funktionslokal als statisch deklariert werden, das ist etwas an
C++ das ich in Java definitiv vermisse...