2017-08-23 2 views
1

Ich bin ein Neuling in C++ und ich habe verschiedene Vorschläge aus anderen Fragen versucht, aber ich kann meinen Code nicht arbeiten."ungültige Verwendung von unvollständigem Typ". Lösen von zirkulären Abhängigkeiten

Ich habe eine Klasse "PChar" und eine andere Klasse "Action". Eine Aktion hat zwei PChar-Mitglieder und eine Methode von PChar ("act()") muss in der Lage sein, ein Action-Objekt zu erstellen. So, nachdem verschiedene Dinge versucht, habe ich diesen Code:

"action.h":

#ifndef ACTION_H 
#define ACTION_H 

class PChar; 

class Action 
{ 
    PChar *subject, *object; 
public: 
    Action(); 
    Action(PChar& p1, PChar& p2); 
}; 


#endif 

"action.cpp":

#include "action.h" 

Action::Action(){}; 

Action::Action(PChar& p1,PChar& p2) 
{ 
    *subject=p1; 
    *object=p2; 
}; 

"character.h"

#ifndef CHARACTER_H 
#define CHARACTER_H 

#include <string> 

#include "action.h" 

class PChar 
{ 
public: 
    std::string name; 

    PChar(); 

    PChar(std::string input_name); 

    void act(PChar& target, Action &action); 
}; 
#endif  

"Zeichen.cpp"

#include "character.h" 

PChar::PChar(){} 

PChar::PChar(std::string input_name) 
{ 
    name=input_name; 
} 

void PChar::act(PChar& target, Action& action) 
{ 
    action=Action(*this, target); 
} 

„main.cpp“

#include "action.h" 
#include "character.h" 

int main() 
{ 
    PChar char1("Joe"); 
    PChar char2("Matt"); 
    Action handshake; 
    char1.act(char2, handshake); 
} 

Das Ziel ist, ein Objekt „Handshake“, die beiden Zeichen als Mitglieder haben zu erstellen. Beim Kompilieren erhalte ich die Fehlermeldung:

action.cpp:7:10: error: invalid use of incomplete type ‘class PChar’ 
    *subject=p1; 
     ^
In file included from action.cpp:1:0: 
action.h:4:7: note: forward declaration of ‘class PChar’ 
class PChar; 
    ^
action.cpp:8:9: error: invalid use of incomplete type ‘class PChar’ 
    *object=p2; 
     ^
In file included from action.cpp:1:0: 
action.h:4:7: note: forward declaration of ‘class PChar’ 
class PChar; 
    ^

Dieser Teil eines größeren Projekts ist, das ist, warum die Dateien so strukturiert sind, ich den Code nur vereinfacht, um den Fehler zu reproduzieren. Ich habe Lösungen aus anderen ähnlichen Fragen versucht, aber sie scheinen nicht zu funktionieren. Jede Hilfe oder Trinkgeld ist willkommen. Vielen Dank!

+0

Mögliche Duplikate von [Resolve-Header enthalten zirkuläre Abhängigkeiten] (https://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies) – user0042

+2

Wenn Sie eine Klasse deklarieren, müssen Sie immer noch die Klasse einschließen Header, der seine Definition vor der Verwendung bereitstellt. Zum Beispiel müssen Sie "character.h" in "action.cpp" einschließen. –

+0

In diesem Beispiel sind schwerwiegende Fehler aufgetreten. '* subject = p1;' wird nicht tun, was Sie wollen. 'subject' ist ein nicht initialisierter Zeiger. Dereferenzierung ist undefiniertes Verhalten. Zumindest müssen Sie eine neue "PChar" als Kopie Ihres Arguments zuweisen. –

Antwort

0

Sie können den Deklarationstyp weiterleiten, um den Zeiger oder den Verweis darauf zu deklarieren. Aber wenn Sie beginnen, diesen Typ zu verwenden (als Wert deklarieren oder ihm zuweisen oder eine Methode aufrufen), muss er definiert werden. Einschließlich character.h in action.cpp würde Kompilierungsfehler lösen. Hinweis Sie haben UB in Ihrem ctor:

Action::Action(PChar& p1,PChar& p2) 
{ 
    *subject=p1; 
    *object=p2; 
} 

wie Sie nicht initialisierte Zeiger dereferenzieren. Sie müssen sie irgendwo zeigen, wahrscheinlich wollten Sie dynamischen Speicher zuweisen. In diesem Fall wäre std::unique_ptr preferrable wie Probleme mit Rule of 3/5/0 lösen würde:

class Action 
{ 
    std::unique_ptr<PChar> subject, object; 
public: 
    ... 
}; 

Action::Action(const PChar& p1, const PChar& p2) : 
    subject(new PChar(p1)), object(new PChar(p2)) 
{ 
} 

und wenn Sie Objekt nicht die Absicht haben, zu modifizieren, besser als konstante Referenz übergeben.

+0

Danke! Gerade, wie Sie gesagt haben, funktioniert, ich weiß nicht, warum ich nicht daran gedacht habe.Ich werde ein bisschen mehr über Zeiger lesen müssen, um zu verstehen, was das Problem dort ist. –

0

C++ muss die Details eines Typs kennen, um kompilieren und zuweisen zu können.

Eine Lösung ist auch in "Action.cpp" aufzunehmen.

Verwandte Themen