Forum: PC-Programmierung GCC Compiler, Klassendefinition und Zugriff auf Member-Variable geht nicht


von Micha R. (michaavr)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe ein kleines Problem mit einem Cpp-Code
und finde den Fehler nicht.

Den Code habe ich im Anhang dazu gepackt.
Ich möchte dazu sagen, dass ich kein C-Profi bin, sondern noch lerne.

Folgendes:
Beim compilieren mit der Gnu-Compiler-Collection erhalte ich folgende 
Fehlermeldung:

include/statemachine.cpp:26:6: error: ‘stateFlags’ was not declared in 
this scope
  if (stateFlags & (1<<FLAG_CHANGED))
      ^

Was ich nicht verstehe ist, dass die anderen Variablen, die genauso 
deklariert wurden funktionieren.

Der Code ist einfach aufgebaut.
Ich möchte eine kleine Klasse schreiben namens Statemachine.
Diese hat 3 Routinen:

 - setState(newState) zum setzen eines neuen Zustandes
 - getState()         zum Abfragen des Zustandes
 - changed()          zum prüfen, ob der Zustand sich geändert hat

Dafür gibt es eine entsprechende Header-Datei und die zugehörige 
Code-Datei. Das ganze rufe ich in mein.cpp zum Testen auf.

Zum kompilieren habe ich eine makefile dabei.

Kann mir jemand den Fehler sagen, warum nur die Variable stateFlags 
angeblich nicht deklariert sein soll, während die anderen Variablen 
(stateCurrend und stateOld) tatellos verarbeitet werden?

Hier mal die Klassendefinition:

#ifndef _statemachine_h
#define _statemachine_h

#include <stdint.h>
#include <stdio.h>

//#include <string.h>

class Statemachine
{

  public:

    Statemachine();  // Constructor

    void setState(uint8_t newState);
    uint8_t getState();
    bool changed();

  private:
    // internal variables
    uint8_t stateCurrent;    // Current State
    uint8_t stateOld;        // Previous State
    uint8_t stateFlags;      // Flags

    // Definitions stateFlags
      #define FLAG_CHANGED 0    // Flag State Changed

};


#endif // _statemachine_h

Wäre toll, wenn ihr mir helfen könnt.
Danke.

Micha

von HeikoG (Gast)


Lesenswert?

Hallo!

changed() ist nicht als Methode der Klasse definert, daher hat diese 
Routine keinen Zugriff auf die member. Es müsste in statemachine.cpp

bool Statemachine::changed()

statt

bool changed()

heissen.

von Micha R. (michaavr)


Lesenswert?

Ojeh,

ich vermute das war ein typischer Anfängerfehler.

Jetzt funktioniert es, vielen Dank!

Micha

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Micha R. schrieb:
> // Definitions stateFlags
>       #define FLAG_CHANGED 0    // Flag State Changed

Was ist das denn?

Ein #define innerhalb einer Klassendeklaration?

Das ist unübersichtlich, und vor allem bezieht es sich nicht auf die 
Klasse, es gilt überall.

von Micha R. (michaavr)


Lesenswert?

Wie gesagt, ich bin da Anfänger.

Vielleicht sollte anstatt '#define' besser 'const' verwendet werden.

Wie definieren und an welcher stelle müsste ich das dann, wenn die 
Konstanten privat nur in der Klasse Gültigkeit haben, definieren?

Micha

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Micha R. schrieb:
> Vielleicht sollte anstatt '#define' besser 'const' verwendet werden.

Genau so.

Sofern sich dem noch weitere Werte hinzugesellen, könntest Du auch ein 
enum verwenden.

> Wie definieren und an welcher stelle müsste ich das dann,

An genau der bisherigen.

Auch bei einem enum wäre das nicht anders, das gehört dann ebenfalls zur 
Klasse.

Und damit ist auch das Namespace-Problem von enums in C umgangen, denn 
das enum gehört zur Klasse.

von Micha R. (michaavr)


Lesenswert?

Wenn ich in der Klassendefinition im Block private schreibe:

  private:
    // internal variables
    uint8_t stateCurrent;    // Current State
    uint8_t stateOld;        // Previous State
    uint8_t stateFlags;      // Flags

        // Definitions stateFlags
        const static uint8_t FLAG_CHANGED = 0;    // Flag State Changed

lässt es sich kcompilieren und FLAG_CHANGED ist in main.cpp ungültig.
So soll es sein.

Aber ohne static gibts Comilier-Fehler.

Muss static in dem Fall sein und
belegt das keinen Speicher (1 Byte)?

Wie wäre es, wenn ich die Definition des Flags
so mache
#define FLAG_CHANGED 0

aber die Definition in Statemachine.cpp, also nicht im Header ablege?
Das hat sich auch compilieren lassen und im main.cpp war das Flag 
unbekannt. Also richtig.



Wäre das eine option?

: Bearbeitet durch User
von Der haarige Erich (Gast)


Lesenswert?

Möglichkeiten:
- static
- In Initialisierungsliste des Konstruktors initialisieren
- enum verwenden

https://stackoverflow.com/questions/14495536/how-to-initialize-const-member-variable-in-a-class

> #define FLAG_CHANGED 0

Nein, das wäre Käse (und FLAG_CHANGED keine Klassenkonstante).

von Der haarige Erich (Gast)


Lesenswert?

BTW: Welche Compilerversion bzw. welche Flags benutzt du eigentlich? 
Einfach "const" sollte natürlich ab C++11 funktioneren:

class Statemachine
{
  const uint8_t FLAG_CHANGED = 0;
};

von Micha R. (michaavr)


Lesenswert?

Danke für die vielen Hinweise

In denke, "static const uint8_t FLAG_CHANGED=0;"

belegt vermutlich ein Byte Speicher.

ich habs jetzt mit enum gelöst.
1
  private:
2
    // internal variables
3
    uint8_t stateCurrent;        // Current State
4
    uint8_t stateOld;        // Previous State
5
    uint8_t stateFlags;          // Flags
6
7
        // Definitions stateFlags
8
        //static const uint8_t FLAG_CHANGED=0;    // Flag State Changed
9
        enum
10
        {
11
            FLAG_CHANGED=0,
12
            FLAG_TIMEOUT=1
13
        };

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.