array as member of class

  • Thread starter =?ISO-8859-1?Q?Florian_B=FCrzle?=
  • Start date
?

=?ISO-8859-1?Q?Florian_B=FCrzle?=

Hi! I've organized my code in different files - the declarations of
global variables and methods are contained in a file global.hh (for
compilation via makefile under Linux). In this file I included the
following:

extern const int dim; //dimension of the array

class Particle{
public:
double x[dim]; //particle position
};


Since dim is defined in another file (where main() is located), the code
does not compile. Does anyone have an idea how this could be fixed? I've
consulted several books, but this doesn't seem to be a common problem
(or I have the wrong books).

Thanks in advance for any advice!

Florian
 
G

Gianni Mariani

Florian said:
Hi! I've organized my code in different files - the declarations of
global variables and methods are contained in a file global.hh (for
compilation via makefile under Linux). In this file I included the
following:

extern const int dim; //dimension of the array

class Particle{
public:
double x[dim]; //particle position
};


Since dim is defined in another file (where main() is located), the code
does not compile. Does anyone have an idea how this could be fixed? I've
consulted several books, but this doesn't seem to be a common problem
(or I have the wrong books).

Thanks in advance for any advice!

Two options.
a) Place the "const int dim = N" in the header.
b) make Particle::x a std::vector
 
I

Ian Collins

Florian said:
Hi! I've organized my code in different files - the declarations of
global variables and methods are contained in a file global.hh (for
compilation via makefile under Linux). In this file I included the
following:

extern const int dim; //dimension of the array

class Particle{
public:
double x[dim]; //particle position
};


Since dim is defined in another file (where main() is located), the code
does not compile. Does anyone have an idea how this could be fixed? I've
consulted several books, but this doesn't seem to be a common problem
(or I have the wrong books).
The array size has to be a compile time constant, it has to be known
when each translation unit that include the header is compiled.

You can either put the value in the header (say a static const unsigned
member), or use a dynamic array.
 
J

Jim Langston

Florian Bürzle said:
Hi! I've organized my code in different files - the declarations of
global variables and methods are contained in a file global.hh (for
compilation via makefile under Linux). In this file I included the
following:

extern const int dim; //dimension of the array

class Particle{
public:
double x[dim]; //particle position
};


Since dim is defined in another file (where main() is located), the code
does not compile. Does anyone have an idea how this could be fixed? I've
consulted several books, but this doesn't seem to be a common problem
(or I have the wrong books).

The compiler has to know what dim is when it gets to this line of code. It
needs to be a constant, but also knowable at compile time. Even if you
declared dim before you included the header, that would probably only work
in one of your compilation units. external linkage is that, linkage, not
compiling.

One solution: use a std::vector<double> isntead of an array. Have
Particle's constructor size it to fit (even using the global if you
absolutely must, but it would be better, IMO, to pass the value through the
constructor's paramater list).
 
?

=?ISO-8859-1?Q?Florian_B=FCrzle?=

Ian said:
The array size has to be a compile time constant, it has to be known
when each translation unit that include the header is compiled.

You can either put the value in the header (say a static const unsigned
member), or use a dynamic array.

Thanks for the quick reply. Can you give me a hint how to implement such
a dynamic array in this case? (Sorry if this is trivial, but I've never
used dynamic arrays).

Thanks!

Florian
 
J

Jim Langston

Florian Bürzle said:
Thanks for the quick reply. Can you give me a hint how to implement such
a dynamic array in this case? (Sorry if this is trivial, but I've never
used dynamic arrays).

Pick one. My preference is Foo.

#include <iostream>
#include <vector>

extern const int dim; //dimension of the array

const int dim = 10;

class Foo
{
public:
Foo( const int Size )
{
x.resize( Size );
}
std::vector<double> x;
};

class Foo2
{
public:
Foo2()
{
x.resize( dim );
}
std::vector<double> x;
};

class Bar
{
public:
Bar( const int Size ) { x = new double[ Size ]; }
~Bar() { delete[] x; }
double* x;
};

class Bar2
{
public:
Bar2() { x = new double[ dim ]; }
~Bar2() { delete[] x; }
double* x;
};

int main()
{
Foo foo( dim );
Foo2 foo2;
Bar bar( dim );
Bar2 bar2;

return 0;
}
 
G

Gianni Mariani

Florian said:
Thanks for the quick reply. Can you give me a hint how to implement such
a dynamic array in this case? (Sorry if this is trivial, but I've never
used dynamic arrays).

Here is some example code.

------------
#include <vector>

// VectDim is basically a vector with a default dimension
// given by a const int reference
template <typename T, const int & D>
class VectDim : public std::vector<T>
{
public:
VectDim() : std::vector<T>( D )
{
}
};

extern const int dim;

class Particle{
public:
VectDim<double,dim> x; //particle position
};


const int dim = 4;

#include <iostream>

int main()
{
Particle p;

std::cout << p.x.size() << "\n";
}
------------
 
B

BobR

Jim Langston said:
Pick one. My preference is Foo.

#include <iostream>
#include <vector>

extern const int dim; // dimension of the array
const int dim = 10;

class Foo
{
public:
Foo( const int Size )
{
x.resize( Size );
}
std::vector<double> x;
};

I prefer 'initialization lists':

class Foo{ public:
Foo( size_t const Size ) : x( Size, 3.14 ){} // OP, note the colon
Foo() : x( dim ){} // 'dim' doubles inited to zero (Foo2 below)
std::vector<double> x;
};
/* - main() or ? -
Foo aFoo( 7 );
std::cout<<" aFoo.x.at(2)="<<aFoo.x.at(2)<<std::endl;
// out: aFoo.x.at(2)=3.140000
*/
class Foo2{ public: // shortened to *my* style for NG post
Foo2(){ x.resize( dim ); }
std::vector<double> x;
};

class Bar{ public:
Bar( const int Size ) { x = new double[ Size ]; }
~Bar() { delete[] x; }
double* x;
};

class Bar{ public:
Bar( size_t const Size ) : x( new double[ Size ] ){}
~Bar() { delete[] x; }
double *x;
};
// 'function level try block' for Ctor not shown.

// Why 'size_t' (unsigned integer type)?
class Bar{ public:
// Bar( int const Size ) : x( new double[ Size ] ){}
// use: Bar aBar( -1 ); runtime-error: bad_alloc

Bar( size_t const Size ) : x( new double[ Size ] ){}
// use: Bar aBar( -1 ); compile-warning
// [Warning] passing negative value `-1'
// for argument 1 of `Bar::Bar(unsigned int)'
// == a HUGE size

~Bar(){ delete[] x; }
double *x;
};

[ snip other examples ]

OP: Jim was keeping it simple so not to confuse you. Look over his post
before you tackle the 'init list' modifications I've shown.
The 'initialization lists; are the prefered way to do it, when you can
(sometimes you must use the body of the constructor (like to set init values
in array[])).
More questions? No problem, ask away.
 
?

=?ISO-8859-1?Q?Florian_B=FCrzle?=

Thanks to all for your help, especially for the code examples!

Florian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top