0
votes

I am attempting to make a Chess module using a ChessPiece struct and a ChessGame struct. Using XCode 6.1.1. Here is my header file and function in question in my Chess.cpp. I get the error, "Use of undeclared identifier 'initChessPiece' did you mean 'ChessPiece::initChessPiece'?. If I make that change it says the error, 'call to non-stack member function without an object argument.' Finally, if I make the line,

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

Linker throws the error:

Undefined symbols for architecture x86_64: "ChessPiece::initChessPiece(ChessPiece, std::__1::basic_string, std::__1::allocator > const&, std::__1::basic_string, std::__1::allocator > const&, unsigned int, unsigned int)", referenced from: readChessGame(ChessGame&, std::__1::basic_string, std::__1::allocator > const&) in Chess.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

#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;
}

This is my CS final practice question and the all the function headers were set by the instructions so I need to work with the way they are setup

4
You're more likely to get help if you include the full, exact error messages (both of them) in your question.Jeffrey Bosboom
Why are you passing the piece to itself (by value) in initChessPiece?Jonathan Potter
Where do you define initChessPiece(...)? Is there some other source file you haven't told us about? And what tool are you using to attempt to build this?Beta
There are basic errors in your code to define ChessPiece. It will be better for you to learn the language using a tutorial or text book before some of the errors you've made will make sense. You can try a basic tutorial at tutorialspoint.com/cplusplus/cpp_classes_objects.htm.R Sahu

4 Answers

1
votes

You need an object of type ChessPiece to be able to call initChessPiece().

Something like this:

#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);
    }
}

You should probably remove the piece parameter since you will have the object available in the function through the this pointer. If you decide to keep it you need to make it a reference or a pointer to be able to change the value of the pieces in your array.

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

EDIT2: void ChessPiece::initChessPiece(const string& colour, const string& name, unsigned int row, unsigned int column) { this->name = name; this->colour = colour; this->row = row; this->column = column; }

I think you should also consider making this a constructor.

Edit: If you want to keep your calling style you could make the initChessPiece() static. Then it should be callable without an object.

0
votes

The problem is in your misunderstanding of method calling syntax. If the method of class is non-static (that means that every object of class has this method and when this method access fields of class it accesses fields of that exact object), you should to tell your compiler from what object you want to call this method. So you should rewrite your code:

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

to

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

and call the method in the way like this:

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

So you take concrete object game, then take its concrete field game.pieces[i] and then call method initChessPiece from that concrete field.

0
votes

As far as I can tell, the error lies in the difference between the declaration and the implementation.

In the declaration (Chess.h), you have void initChessPiece(ChessPiece [...] while in the implementation (Chess.cpp), you have initChessPiece(ChessPiece& [...]. Add the & in your header file and it should work properly.

0
votes

Try changing signatures of initChessPiece to this:

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

Then call initChessPiece using object.Member() syntax, like this:

#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);
}
}