2014-12-16 2 views
0

Я пытаюсь создать шахматный модуль, используя структуру ChessPiece и структуру ChessGame. Использование XCode 6.1.1. Вот мой заголовочный файл и функция, о которых идет речь в моем Chess.cpp. Я получаю сообщение об ошибке: «Использование необъявленного идентификатора« initChessPiece »вы имели в виду« ChessPiece :: initChessPiece »? Если я сделаю это изменение, он говорит об ошибке« вызов функции не-стека без аргумента объекта ». И, наконец, если я линия,Тело функции C++, вызывающее другую функцию structs, тот же модуль

game.pieces[i].initChessPiece(game.pieces[i], color, piece, x, y); 

Linker бросает ошибка:

неопределенных символов для архитектуры x86_64: «Фишка :: initChessPiece (фишка, станд :: __ 1 :: basic_string, станд :: __1 :: allocator> const &, std :: __ 1 :: basic_string, std :: __ 1 :: allocator> const &, unsigned int, unsigned int) ", на который ссылаются: readChessGame (ChessGame &, std :: __ 1 :: basic_string, std :: __ 1 :: allocator> const &) в Chess.o ld: символы (символы) не найдены для архитектуры x86_64 лязг: ошибка: команда линкер потерпела неудачу с кодом выхода 1 (используйте опцию -v, чтобы вызов)

#ifndef CHESS_H 
#define CHESS_H 

#include <stdio.h> 
#include <string> 

using namespace std; 

const int ROWS = 8; 
const int COLUMNS = 8; 

struct ChessPiece { 

string name; 
string colour; 
unsigned int row; 
unsigned int column; 
void initChessPiece(ChessPiece, const string& colour, const string& name, unsigned int row, unsigned int column); 
string getStringColourChessPiece(const ChessPiece&) const; 
string getStringNameChessPiece(const ChessPiece&) const; 

friend class ChessGame; 
}; 

struct ChessGame { 
unsigned int chessBoard[ROWS][COLUMNS]; 
ChessPiece pieces[32]; 

void readChessGame(ChessGame&, const string& filename); 
void printChessGame(const ChessGame&); 
int scoreChessGame(const ChessGame&) const; 
bool isFinished(const ChessGame&) const; 
}; 


#endif 

Chess.cpp

#include "Chess.h" 
void readChessGame(ChessGame& game, const string& filename) { 

ifstream inData; 
inData.open(filename.c_str()); 

string color; 
string piece; 
unsigned int x; 
unsigned int y; 
for (int i=0;i<32;i++) { 
    inData >> color >> piece >> x >> y; 
    initChessPiece(game.pieces[i], color, piece, x, y); 
} 
} 

void initChessPiece(ChessPiece& piece, const string& colour, const string& name, unsigned int row, unsigned int column) { 
piece.row = row; 
piece.column = column; 
piece.name = name; 
piece.colour = colour; 
} 

Это мой последний вопрос практика CS и все функциональные заголовкам были установлены инструкциями, поэтому мне нужно работать с тем, как они устанавливаются.

+0

У вас больше шансов получить помощь, если вы включите в свой вопрос полные точные сообщения об ошибках (оба из них). –

+0

Почему вы передаете кусок себе (по значению) в 'initChessPiece'? –

+0

Где вы определяете 'initChessPiece (...)'? Есть ли какой-то другой исходный файл, о котором вы нам не говорили? И какой инструмент вы используете, чтобы попытаться построить это? – Beta

ответ

1

Для того, чтобы позвонить по телефону initChessPiece(), нужен объект типа ChessPiece.

Что-то вроде этого:

#include "Chess.h" 
void readChessGame(ChessGame& game, const string& filename) { 

    ifstream inData; 
    inData.open(filename.c_str()); 

    string color; 
    string piece; 
    unsigned int x; 
    unsigned int y; 
    for (int i=0;i<32;i++) { 
     inData >> color >> piece >> x >> y; 
     game.pieces[i].initChessPiece(game.pieces[i], color, piece, x, y); 
    } 
} 

Вы, вероятно, следует удалить параметр кусок, так как вы будете иметь объект доступны в функции через this указатель. Если вы решили сохранить его, вам нужно сделать ссылку или указатель, чтобы иметь возможность изменять значение частей в вашем массиве.

game.pieces[i].initChessPiece(color, piece, x, y); 

EDIT2: недействительная фишка :: initChessPiece (Const строки & цвет, Const строки & имя, беззнаковая целочисленное значение строка, беззнаковый целочисленное значение столбец) { этом-> имя = имя; это-> цвет = цвет; this-> row = row; this-> column = column; }

Я думаю, вы также должны рассмотреть возможность создания этого конструктора.

Редактировать: Если вы хотите сохранить свой стиль звонка, вы можете сделать статическое изображение initChessPiece(). Тогда он должен быть доступен без объекта.

+0

Я попытался позвонить функцию из объекта game.pieces [i], но затем я получаю ошибку компоновщика с моего основного сообщения. Также, когда я помещаю это-> имя и т. Д., Я получаю сообщение об ошибке «Недопустимое использование« этого »вне нестатической функции-члена. –

+0

Извините, я отредактировал свой ответ. (Edit2) Вам нужно определить определение своего fuction. – warsac

+0

Насколько я понимаю и после тестирования вам не нужно/не может выполнять разрешение области для функций struct, нужны только функции класса. То же самое с «this» –

0

Проблема заключается в вашем непонимании синтаксиса вызова метода. Если метод класса не статичен (это означает, что каждый объект класса имеет этот метод и когда этот метод обрабатывает поля класса, он обращается к полям этого точного объекта), вы должны сообщить своему компилятору, с какого объекта вы хотите вызовите этот метод. Таким образом, вы должны переписать код:

void initChessPiece(ChessPiece, const string& colour, const string& name, unsigned int row, unsigned int column); 

к

void initChessPiece(const string& colour, const string& name, unsigned int row, unsigned int column); 

и вызвать метод в пути, как это:

game.pieces[i].initChessPiece(color, piece, x, y); 

Так вы берете конкретный объект game, а затем взять его конкретное поле game.pieces[i], а затем вызывать метод initChessPiece из этого конкретного поля.

0

Попробуйте изменить подписи initChessPiece к этому:

void initChessPiece(const string& colour, const string& name, unsigned int row, unsigned int column); 

Затем вызовите initChessPiece с использованием синтаксиса object.Member(), например:

#include "Chess.h" 
void readChessGame(ChessGame& game, const string& filename) { 

ifstream inData; 
inData.open(filename.c_str()); 

string color; 
string piece; 
unsigned int x; 
unsigned int y; 
for (int i=0;i<32;i++) { 
    inData >> color >> piece >> x >> y; 
    game.pieces[i].initChessPiece(color, piece, x, y); 
} 
} 
+0

Вот как я обычно это делал, но я изучаю для своего CS Final, и это примерный вопрос, поэтому я должен использовать structs и передавать объект в качестве параметра. –

+0

Я изменил образец кода, чтобы использовать struct и передать объект как параметр readChessGame. – regmagik

+0

Если вы действительно должны передать 'ChessPiece &' в 'initChessPiece', вы можете объявить его как static: ' static initChessPiece (ChessPiece & piece, const string & color, const string & name, unsigned int row, unsigned int column); 'и call via ChessPiece :: initChessPiece, но это не рекомендуется для стиля C++. – regmagik

0

Насколько я могу сказать, ложь об ошибке в отличие от декларации и реализации.

В декларации (Chess.h) у вас есть пустота initChessPiece(ChessPiece [...], а во внедрении (Chess.cpp) у вас есть initChessPiece(ChessPiece& [...]. Добавьте & в файл заголовка, и он должен работать правильно.