Compilererror im Zusammenhang mit Funktionspointern
-
Ich versuche ein ganz einfahces Beispiel aus dem Buch "Practical Statecharts in C / C++. Quantum Programming for Embedded Systems" zu kompilieren.
Der Compiler bricht mit folgender Fehlermeldung ab:$ gcc Qhsmtst1.cpp Qhsmtst1.cpp: In constructor `QHsmTst::QHsmTst()': Qhsmtst1.cpp:17: error: argument of type `void (QHsmTst::)(const QEvent*)' does not match `void (QHsm::*)(const QEvent*)'Die entsprechende Zeile in Qhsmtst1.cpp ist:
[cpp]class QHsmTst : public QHsm {
public:
QHsmTst() : QHsm((QPseudoState)initial) {} // Zeile 17
protected:
[/cpp]QPseudoState ist eine Typdefinition und wird in Qhsm.h spezifiziert:
class QHsm { // Quantum Hierarchical State Machine public: typedef void (QHsm::*QPseudoState)(QEvent const*); // pseudostate typedef QPseudoState (QHsm::*QState)(QEvent const*); // stateIm Ordner in dem die ganzen Quelldateien liegen befinden sich auch einige Visual Studio Projektdateien. Das Beispiel aus dem Buch wurde also offensichtlich mit dem Microsoftcompiler (und nicht dem GCC den ich benutze) kompiliert. Ich benutze:
gcc (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125)
Kennt jemand ein Workaround für mein Problem?
Gruß und Segen,
Christoph
-
Wie sieht die ganze QHsm Klasse aus?
-
///////////////////////////////////////////////////////////////////// // Quantum Hierarchical State Machine declaration (C++ version) // Copyright (c) 2002 Miro Samek, Palo Alto, CA. // All Rights Reserved. ///////////////////////////////////////////////////////////////////// #ifndef qhsm_h #define qhsm_h #ifndef qevent_h #include "qevent.h" #endif class QHsm { // Quantum Hierarchical State Machine public: typedef void (QHsm::*QPseudoState)(QEvent const*); // pseudostate typedef QPseudoState (QHsm::*QState)(QEvent const*); // state void init(QEvent const *e = 0); // execute initial transition void dispatch(QEvent const *e); // dispatch event int isIn(QState state); // "is-in-state" query static char const *getVersion(); protected: struct Tran { // protected inner class Tran QState myChain[7]; unsigned short myActions; // action mask (2-bits for action) }; QHsm(QPseudoState initial); // ctor virtual ~QHsm(); // virtual xtor QPseudoState top(QEvent const*) { return 0; } // the "top" state QState getState() const { return myState; } void tran(QState target); // dynamic state transition void tranStat(Tran *t, QState target); // static state transition void init_(QState target) { myState = target; } #define Q_INIT(target_) init_(Q_STATIC_CAST(QState, target_)) #define Q_TRAN(target_) if (1) { \ static Tran t_; \ tranStat(&t_, Q_STATIC_CAST(QState, target_));\ } else ((void)0) #define Q_TRAN_DYN(target_) tran(Q_STATIC_CAST(QState, target_)) private: void tranSetup(Tran *t, QState target); private: QState myState; // the active state QState mySource; // source state during a transition }; typedef QHsm::QPseudoState QSTATE; // state-handler return type // helper macro to calculate static dimension of a 1-dim array #define DIM(array_) (sizeof(array_)/sizeof(*(array_))) #endif // qhsm_hbitte nicht verklagen

-
Im Konstruktor von QHsmTst ist ein Fehler, da auf einen Klassenzeiger der (ich nehme an) Basisklasse QHsm zugegriffen wird. Leider werden Klassenzeiger nicht vererbt, d.h. es muß ein expliziter cast gemacht werden, z.B.
(void (QHsmTst::)(const QEvent*)) (pointer)bzw. mittels eines Typedefs:
static_cast<QHsm::QPseudoState>(pointer)Da sind wohl die anderen Compiler nicht Standard-C++ konform...
Ansonsten zeig mal den Inhalt des Konstruktors von QHsmTest.
-
Hallo,
Danke für deine Antwort Th.
Das Zeiger auf QEvent wird in der Datei Qevent.h deklariert. Ist also kein Klassenpointer der in der Klasse QHsm deklariert wurde.
Den Inhalt des Konstruktors QHsmtst hast du breits vor dir.QHsmTst() : QHsm((QPseudoState)initial) {}ist ja direkt die definition des C'tors.
-
Sorry, ich war so blind, daß ich das Fettgedruckte nicht gelesen habe...
Und ich hatte auch noch einen Tippfehler bei mir:
(void (QHsm::*)(const QEvent*)) (pointer)Mit Klassenpointer meinte ich "QHsm::*".
Aber was ist "initial" denn bei dir (ich nehme an eine Methode der Klasse "QHsmTst")?
Hier mal ein Beispiel von mir, daß ich selbst mal als Test benötigt habe, um dies zu verstehen.
class A { public: typedef void (A::*MemberFunc)(); A(MemberFunc f) { m_f = f; } void DoIt() { (this->*m_f)(); } private: MemberFunc m_f; }; class B : public A { public: B() : A((MemberFunc)&B::bf) { x = 42; } void bf() { std::cout << x << std::endl; } private: int x; };Wie du siehst, übergebe ich "&B::bf".
Evtl. mußt du auch bei dirQHsmTst() : QHsm((QPseudoState)&HsmTst::initial) {}schreiben.
-
@Th: vielen danak. du hast mir sehr geholfen.