2016-05-14 3 views
1

Ich habe einige C++ - Code, der in Visual Studio 2013 gut kompiliert wird, aber nicht in Linux mit g ++ (keine IDE) kompilieren.Code Compilierung schlägt unter Linux fehl, Erfolg unter Windows: Ursache/Behebung?

Was verursacht den Unterschied und wie kann ich den Code auf Linux kompilieren? Liegt es daran, dass sie verschiedene Compiler sind? Brauche ich eine bestimmte Compiler-Einstellung?

Code:

#include <iostream> 

typedef class IApp; 
typedef class Component; 

class Component 
{ 
public: 

protected: 
    IApp* app; 

    template<typename T> 
    void registerEvent() 
    { 
     app->logEvent(); 
    } 
}; 

class IApp : protected Component 
{ 
public: 
    static IApp NULL_APP; 

    void logEvent() 
    { 
     printf("Event Logged\n"); 
    } 

protected: 
    virtual void foo() = 0; 
}; 


int main(int argc, char** argv) 
{ 
    printf("Alive\n"); 
    system("pause"); 
    return 0; 
} 

Auf Fenster bekomme ich keine Compiler-Fehler. Unter Linux bekomme ich den folgenden Compiler-Fehler:

g++ - o res main.cpp - std = c++11 
main.cpp:3 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default] 
typedef class IApp; 
^ 
main.cpp:4 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default] 
typedef class Component; 
^ 
main.cpp: In member function ‘void Component::registerEvent()’ : 
main.cpp : 16 : 6 : error : invalid use of incomplete type ‘class IApp’ 
app->logEvent(); 
^ 
main.cpp:3 : 15 : error : forward declaration of ‘class IApp’ 
typedef class IApp; 
^ 
main.cpp: At global scope : 
main.cpp : 23 : 14 : error : cannot declare variable ‘IApp::NULL_APP’ to be of abstract type ‘IApp’ 
static IApp NULL_APP; 
^ 
main.cpp:20 : 7 : note : because the following virtual functions are pure within ‘IApp’ : 
class IApp : protected Component 
    ^
    main.cpp : 31 : 15 : note : virtual void IApp::foo() 
    virtual void foo() = 0; 
^ 
make: ***[all] Error 1 

Antwort

3

Hier sollen Sie einfach typedef entfernen:

typedef class IApp; 

Dann sollte diese Vorlage Methode out-of-line definiert werden, unter IApp:

template<typename T> 
void registerEvent() 
{ 
    app->logEvent(); 
} 

Andernfalls wird die Deklaration von IApp, die es dereferenzieren muss, nicht angezeigt.

Schließlich ist dies nicht sinnvoll:

virtual void foo() = 0; 

Da die gleiche Klasse ein static Mitglied seiner eigenen Klassentyp hat, so ist es instanziiert muss. Aber das hast du mit einer rein virtuellen Funktion verhindert.

GCC ist richtig, diesen Code nicht zu kompilieren.

1

Lassen Sie die typedef-Schlüsselwörter vor den forward-Klasse-Deklarationen aus, sie sind nicht erforderlich. Nur Klasse MyClass; ist ausreichend für eine Vorwärtsdeklaration. Das andere Problem ist, dass foo() rein virtuell ist - Sie müssen es implementieren, wenn Sie die Klasse instanziieren möchten. Ich bin überrascht, dass der Microsoft Compiler sich nicht beschwert, aber dann ist das Microsoft.