• Advertisement
Sign in to follow this  

arrays in classes

This topic is 4518 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to initialize an array based off of information the user passes into the class, howerver, I keep getting an error.
Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\Cal\My Documents\chess_08.06.2005\Chess1Player\Makefile.win"
Executing  make clean
rm -f main.o bishop.o chessBoard.o chessPiece.o king.o knight.o pawn.o queen.o rook.o chessAuxFunctions.o  Chess1Player.exe

g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   

In file included from main.cpp:6:
alphaBetaTree.h:45: error: invalid use of non-static data member `alphaBetaTree::MAX_GENERATION'
alphaBetaTree.h:51: error: from this location
alphaBetaTree.h:45: error: invalid use of non-static data member `alphaBetaTree::MAX_GENERATION'
alphaBetaTree.h:52: error: from this location
alphaBetaTree.h: In member function `void alphaBetaTree::updateKillerMove(int, const move&)':
alphaBetaTree.h:60: error: `killerMoves' undeclared (first use this function)
alphaBetaTree.h:60: error: (Each undeclared identifier is reported only once for each function it appears in.)
alphaBetaTree.h:62: error: `killerMoveIndex' undeclared (first use this function)

alphaBetaTree.h: In member function `std::vector<move, std::allocator<move> >& alphaBetaTree::generateMoves(std::vector<move, std::allocator<move> >&, const chessBoard&, bool, int)':
alphaBetaTree.h:110: error: `killerMoves' undeclared (first use this function)

make.exe: *** [main.o] Error 1

Execution terminated


My question is why is the compiler complaining?
//you can initialize an array this way
const int size = 3;
int array[3];

//i get an error when doing this
class A {
  // initialize x through constructor paramater
 public:
  A(int size): x(size) { }

 private:
  const int x;
  int array[x];  //error here
};


Why does the compiler complain about this?

Share this post


Link to post
Share on other sites
Advertisement
You can't dynamically allocate an array like that. Consider using a std::vector instead.

Share this post


Link to post
Share on other sites

#include <vector>
using namespace std;

class A {
// initialize x through constructor paramater
public:
A(int size): x(size) {array.resize(x);}

private:
const int x;
vector<int> array;
};



std::vector is t3h r0x0rz!!~!

But seriously, it makes things a lot easier and it's a lot faster than any dynamic array most people could code themselves.

Share this post


Link to post
Share on other sites
This should also work:


class A
{

public:
A(int size)
{
x = size;
array = new int[x];
}
~A() { delete array; }

private:
const int x;
int *array;
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Stompy9999
This should also work:

*** Source Snippet Removed ***

Be warned though, if you try and copy this object it will copy the pointer and NOT create a new array for the new object. When you then destroy both the original and the copy, you'll be trying to delete the same pointer twice.

Share this post


Link to post
Share on other sites
Thusly you would want to make a copy constructor, I think like this:
class A {
public:
//Constructor and destructor here
//Is this how you do a copy constructor?
A(const A &src) {
x=src.x;
array=new int[x];
memcpy(array,src.array,sizeof(int)*x);
}
//Also, I'm not sure how well this will work with private members...
private:
const int x;
int *array;
};

Also, you might want to define an overload for "operator=" too.

Share this post


Link to post
Share on other sites
If you use the vector, having a data member to track the size is redundant; the vector already contains that option.

If you use an array you will indeed need to copy things manually. This should work (and exhibit "proper style" for doing each of the tasks, and look after little details like exception safety):


class A {
const int size;
int* data;
public:
// Initializer lists are your friends.
A(int size = 0) : size(size), data(new int[size]) {}
// delete[] what you new[] (and delete what you new).
~A() { delete[] data; }
A(const A& other) : size(other.size), data(new int[other.size]) {
// We make use of the std::copy algorithm to copy the data. The compiler
// does template magic behind the scenes to optimize the copy as well as
// it knows how to (google 'tag dispatching'), and we don't have to care
// about the sizeof() what we're copying.
std::copy(other.data, other.data + other.size, data);
}
A& operator= (const A& rhs) {
// Here, the copy-and-swap idiom provides exception safety and also
// handles self-assignment without error (although inefficiently).
// At the end of function, rhs falls out of scope, and the dtor call
// will delete[] our 'data' pointer which we swapped out to that object.
// The exception safety is provided by the fact that an exception in the
// copy construction will just result in the unswapped, broken rhs being
// taken back apart, leaving this object untouched. (Such an exception
// would occur in an out-of-memory condition, basically.)
A other(rhs);
size = other.size;
std::swap(data, other.data);
return *this;
}
};

Share this post


Link to post
Share on other sites
Use stl::vector and don't worry about copy operators and destructors... let stl do it for you while you do something more important.

Share this post


Link to post
Share on other sites
Has anyone else noticed the small detail that size has been a const int in all these examples and assignment to size would not be a happy thing?

Share this post


Link to post
Share on other sites
Uhh... Yeah, I was actually wondering how classes would actually deal with constant variables, if they weren't static... Wouldn't it only work as a "static const"?

Share this post


Link to post
Share on other sites
You can have non-static const members in classes. You need to initialize the member in the member initialization list in the constructor; and you can't assign to it or otherwise change it without a const_cast. But otherwise they work like you would expect a const variable to work. Which means the constructors in the first few examples are illegal since they assign to size in the constructor body, and the assignment operator in Zahlman's example is non-kosher because it tries to assign to the size member.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement