C ++ / Classes中相互依赖的循环依赖关系

时间:2013-10-13 08:35:37

标签: c++ circular-dependency forward-declaration circular-reference

我有以下问题:

我有一个Pawn,站在Field上。所以我有Class Pawn和Class Field。我希望能够从Field上访问站在它上面的Pawn,我希望能够从Pawn访问它所站立的Field。

所以我有课程:

class Pawn;
class Player;
class Field;
class PlayerList;

class Pawn
{
    public:
        int intID;
        Player* plrPlayer;
        Field* fldField;

        ...

 int getPosition()
{
    //gets the ID of the Field it stands on 
    return fldField->intID; //Here i get the error
}
}

class Field
{
    public:
    Pawn* pwnPawn;
    int intID;
    Field()
    {
        intID = -1;
    }
    Field(int intIDParam)
    {
        intID = intIDParam;
    }
};

g ++说

Error: invalid use of incomplete type "class Field"
Error: Forward declaration of class Field

    main.cpp: In Elementfunktion »int Pawn::getPosition()«:
    main.cpp:42:24: Fehler: falsche Benutzung des unvollständigen Typs »class Field«
    main.cpp:10:7: Fehler: Vorwärtsdeklaration von »class Field«

除了在课堂外宣布事情之外还有其他方法吗?或者我真的必须在我需要之前声明所有方法/成员吗?

我该怎么办?谢谢。

编辑: 谢谢,但我现在尝试将它分成.h和.cpp文件。稍后我将为每个类使用.h和.cpp文件,但现在我只需要

header.h

#ifndef _HEADERS_
#define _HEADERS_
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <vector>
using namespace std;

class Pawn;
class Player;
class Field;
class PlayerList;

class Pawn
{
    public:
        int intID;
        Player* plrPlayer;
        Field* fldField;

//Constructors....

int getPosition();
...
};
#endif 

implementations.cpp

#ifndef _IMPLEMENTATIONS_
#define _IMPLEMENTATIONS_
#include "headers.h"
//Pawn.cpp
int Pawn::getPosition()
{
    return fldField->intID;
}

...

#ENDIF

在main.cpp中我包含“implements.cpp”

我收到错误

In function Pawn::getPosition
multiple definition of Pawn::getPosition

我做错了什么?

3 个答案:

答案 0 :(得分:0)

单独的声明和实现。在单独的cpp文件中实现类。应该是这样的:

头文件:

class Player;
class Field;
class PlayerList;

class Pawn
{
    public:
        int intID;
        Player* plrPlayer;
        Field* fldField;

        ...

 int getPosition();

}

class Field
{
    public:
    Pawn* pwnPawn;
    int intID;
    Field()
    {
        intID = -1;
    }
    Field(int intIDParam)
    {
        intID = intIDParam;
    }
};

C ++文件:

#include <header...>

int Pawn::getPosition()
{
    //gets the ID of the Field it stands on 
    return fldField->intID; //Here i get the error
}

普遍接受的做法是不将多个类放在同一个翻译单元中,但这更像是一个指导,使代码更清晰。

答案 1 :(得分:0)

使用声明而不是类Pawn中的定义:

int getPosition() const;
在类Field之后

,实现它:

int Pawn::getPosition() const
{
    //gets the ID of the Field it stands on 
    return fldField->intID;
}

(注意我添加了const,因为get建议此方法不应修改它正在处理的实例)

您稍后会想要将声明和定义分成标题和实现文件,另一个答案已经有了一些信息。


分隔标题,创建pawn.hfield.h。我想你知道怎么做。

您的实施文件pawn.cpp应如下所示:

// note: no include guards for the 
#include "pawn.h" // you need the header for pawn
#include "field.h" // and the header for field since here you are using it

int Pawn::getPosition()
{
    return fldField->intID;
}

您对field.cpp执行相同的操作。然后单独编译这些文件,同时main.cpp不应包含*.cpp文件。

要编译并将所有内容链接在一起,这应该可以帮助您入门:

# compile each source file into an object file
g++ -Wall -c field.cpp -o field.o
g++ -Wall -c pawn.cpp -o pawn.o
g++ -Wall -c main.cpp -o main.o
# link them together into an executable
g++ field.o pawn.o main.o -o main
# run the executable
./main

答案 2 :(得分:0)

你得到错误的原因是你在Pawn.h中转发声明的Field(这很好!),但是你已经实现了一个在头文件中使用Field对象的函数。

编译器想知道intID是什么,因为你没有指定Field的定义。

正如littleadv很好地解释的那样,将它们分开并将标题包含在.cpp文件中(或) 删除头文件中的前向声明并包含Field.h