arrays in classes

Started by
10 comments, last by Nerusai 18 years, 7 months ago
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?
Advertisement
You can't dynamically allocate an array like that. Consider using a std::vector instead.
#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.
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;};
-----------------------------Play Stompy's Revenge! Now!
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.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
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.
Projects:> Thacmus - CMS (PHP 5, MySQL)Paused:> dgi> MegaMan X Crossfire
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;  }};
Use stl::vector and don't worry about copy operators and destructors... let stl do it for you while you do something more important.
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?
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"?
Projects:> Thacmus - CMS (PHP 5, MySQL)Paused:> dgi> MegaMan X Crossfire

This topic is closed to new replies.

Advertisement