у меня следующая проблема:
У меня есть пешка, которая стоит на поле. Итак, у меня есть Пешка класса и Поле класса. Я хочу иметь доступ с Поля к Пешке, которая стоит на ней, и я хочу иметь доступ от Пешки к Полю, на котором она стоит.
Итак, у меня есть классы:
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 я включаю «Implementations.cpp»
Я получаю ошибку
In function Pawn::getPosition
multiple definition of Pawn::getPosition
Что я делаю не так?
Отдельные объявления и реализации. Реализуйте классы в отдельных файлах 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;
}
};
#include <header...>
int Pawn::getPosition()
{
//gets the ID of the Field it stands on
return fldField->intID; //Here i get the error
}
Это также общепринятая практика — не помещать несколько классов в одну единицу перевода, но это скорее руководство, которое делает код чище.
Причина, по которой вы получаете ошибку, заключается в том, что вы перенаправили объявленное поле в Pawn.h (что хорошо!), Но вы реализовали функцию, которая также использует объект Field в заголовочном файле.
Компилятору остается задаться вопросом, что такое intID, поскольку вы не указали определение Field.
Как мило объяснил littleadv, выделите их и включите заголовок в файл .cpp (или)
удалите предварительную декларацию в вашем заголовочном файле и включите Field.h
Используйте объявление вместо определения в классе Pawn
:
int getPosition() const;
а также после класс Field
, внедри это:
int Pawn::getPosition() const
{
//gets the ID of the Field it stands on
return fldField->intID;
}
(примечание я добавил const
как get
предположить, что этот метод не должен изменять экземпляр, на котором он работает)
Позже вы захотите разделить объявления и определения в файлах заголовка и реализации, другой ответ уже содержит некоторую информацию об этом.
Разделите заголовки, создайте pawn.h
а также field.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