问题
I am working on editing some old C++ code that uses global arrays defined like so:
int posLShd[5] = {250, 330, 512, 600, 680};
int posLArm[5] = {760, 635, 512, 320, 265};
int posRShd[5] = {765, 610, 512, 440, 380};
int posRArm[5] = {260, 385, 512, 690, 750};
int posNeck[5] = {615, 565, 512, 465, 415};
int posHead[5] = {655, 565, 512, 420, 370};
I want to make all of these arrays private members of the Robot class defined below. However, the C++ compiler does not let me initialize data members when I declare them.
class Robot
{
private:
int posLShd[5];
int posLArm[5];
int posRShd[5];
int posRArm[5];
int posNeck[5];
int posHead[5];
public:
Robot();
~Robot();
};
Robot::Robot()
{
// initialize arrays
}
I want to initialize the elements of these six arrays in the Robot() constructor. Is there any way to do this other than assigning each element one by one?
回答1:
If your requirement really permits then you can make these 5 arrays as static
data members of your class and initialize them while defining in .cpp file like below:
class Robot
{
static int posLShd[5];
//...
};
int Robot::posLShd[5] = {250, 330, 512, 600, 680}; // in .cpp file
If that is not possible then, declare this arrays as usual with different name and use memcpy()
for data members inside your constructor.
Edit:
For non static members, below template
style can be used (for any type like int
). For changing the size, simply overload number of elements likewise:
template<size_t SIZE, typename T, T _0, T _1, T _2, T _3, T _4>
struct Array
{
Array (T (&a)[SIZE])
{
a[0] = _0;
a[1] = _1;
a[2] = _2;
a[3] = _3;
a[4] = _4;
}
};
struct Robot
{
int posLShd[5];
int posLArm[5];
Robot()
{
Array<5,int,250,330,512,600,680> o1(posLShd);
Array<5,int,760,635,512,320,265> o2(posLArm);
}
};
C++11
The array initialization has now become trivial:
class Robot
{
private:
int posLShd[5];
...
public:
Robot() : posLShd{0, 1, 2, 3, 4}, ...
{}
};
回答2:
you can either make it static, or use the new initialisation introduced in C++0x
class Robot
{
private:
int posLShd[5];
static int posLArm[5];
// ...
public:
Robot() :
posLShd{250, 330, 512, 600, 680} // only C++0x
{}
~Robot();
};
int Robot::posLArm[5] = {760, 635, 512, 320, 265};
回答3:
To throw one other approach into the mix (and one that doesn't tell you to make the array data members static
as most of the other answers do – I assume you know whether or not they should be static
), here's the zero-overhead approach I use: Make static
member functions and have them return std::array<>
(or boost::array<> if your compiler is too old to come with a std::
or std::tr1::
implementation):
class Robot
{
static std::array<int, 5> posLShd_impl() { std::array<int, 5> x = {{ 250, 330, 512, 600, 680 }}; return x; }
static std::array<int, 5> posLArm_impl() { std::array<int, 5> x = {{ 760, 635, 512, 320, 265 }}; return x; }
static std::array<int, 5> posRShd_impl() { std::array<int, 5> x = {{ 765, 610, 512, 440, 380 }}; return x; }
static std::array<int, 5> posRArm_impl() { std::array<int, 5> x = {{ 260, 385, 512, 690, 750 }}; return x; }
static std::array<int, 5> posNeck_impl() { std::array<int, 5> x = {{ 615, 565, 512, 465, 415 }}; return x; }
static std::array<int, 5> posHead_impl() { std::array<int, 5> x = {{ 655, 565, 512, 420, 370 }}; return x; }
std::array<int, 5> posLShd;
std::array<int, 5> posLArm;
std::array<int, 5> posRShd;
std::array<int, 5> posRArm;
std::array<int, 5> posNeck;
std::array<int, 5> posHead;
public:
Robot();
};
Robot::Robot()
: posLShd(posLShd_impl()),
posLArm(posLArm_impl()),
posRAhd(posRAhd_impl()),
posRArm(posRArm_impl()),
posNeck(posNeck_impl()),
posHead(posHead_impl())
{ }
回答4:
Is there any way to do this other than assigning each element one by one?
If you wish to fill all the elements of array with some default values, std::fill
can be used.
#include <algorithm>
// ...
Robot::Robot()
{
std::fill(posLShd, posLShd+5, 13 ) ; // 13 as the default value
// Similarly work on with other arrays too.
}
If each element of the array needs to be filled with a different value, then assigning value at each index is the only option.
回答5:
Leave the globals in the code and then initialize the local arrays with memcpy(), copying the contents of the global arrays to the local ones.
回答6:
// class definition with incomplete static member could be in a header file
Class Robot {
static const int posLShd[5];
....
// this needs to be placed in a single translation unit only
const int Robot::posLShd[5] = {250, 330, 512, 600, 680};
回答7:
Not really, although I agree with stefaanv's comment - if they were global previously, making them static would get you the "easy assignment", and they seem as though they may be const static at a glance.
If these values are something you change occasionally, you might consider reading them in from an external file on class creation, such that you can avoid recompiles.
You also might consider using std::vector instead of the fixed arrays for some of the features it provides.
回答8:
Am I missing something here? The code below works. Simply declare the members, and initialize right away.
#include <iostream>
class Robot {
public:
int posLShd[5] = {250, 330, 512, 600, 680};
int posLArm[5] = {760, 635, 512, 320, 265};
int posRShd[5] = {765, 610, 512, 440, 380};
int posRArm[5] = {260, 385, 512, 690, 750};
int posNeck[5] = {615, 565, 512, 465, 415};
int posHead[5] = {655, 565, 512, 420, 370};
public:
Robot() {}
~Robot() {}
};
int main () {
Robot obj;
for (int i = 0;i < 5;i++) {
std::cout << obj.posRArm[i] << std::endl;
}
}
来源:https://stackoverflow.com/questions/5643923/c-initializing-non-static-member-array