Forum: PC-Programmierung c++ statische methoden + Linker fehlermeldung


von Flutsch1987 (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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?

von Flutsch1987 (Gast)


Lesenswert?

@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

von Timo (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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...

von Frank B. (foobar)


Lesenswert?

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
class Test {
2
public:
3
static void test() {}
4
};
5
6
void main()  {
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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Flutsch1987 (Gast)


Lesenswert?

@ 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..

von Flutsch1987 (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Flutsch1987 (Gast)


Lesenswert?

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...

von U.R. Schmitt (Gast)


Lesenswert?

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.

von Flutsch1987 (Gast)


Lesenswert?

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..

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.