Monday 10 December 2018

pointers - C++ Vector Arrays in Copy Constructors



I am new to copy constructors and can't seem to get them working when I start using vectors.



//  ROBOT CLASS
class Robot {
private:
char *name;
int size;


int cmdCount;

command *cmdList;
char items[8][16];
int resources[3]; // silver, gold, then platinum

public:
Robot( );
Robot(int num_of_cmds, const char *nm);

Robot(const Robot &);
~Robot( );

const char *get_name( );
command get_command(int pos) const;
void set_item(const char item[ ], int pos);
const char *get_item(int pos);

};


// ROBOT CONSTRUCTOR default
Robot::Robot( ) {

// Load Robot name
cmdCount = 5;
try {
name = new char[11];
}
catch(std::bad_alloc) {
cout << "Error allocating " << 11+1 << " bytes of memory\n";

name = NULL;
}

if (name) {
strcpy (name, "univac.dat");
}

// Allocate memory for command array
vector cmdList[5];


};

// ROBOT COPY CONSTRUCTOR
Robot::Robot(const Robot &from) {
cmdCount = from.cmdCount;
// Load Robot name
try {
name = new char[11];
}
catch(std::bad_alloc) {

cout << "Error allocating " << 11+1 << " bytes of memory\n";
name = NULL;
}

if (name) {
strcpy (name, from.name);
}

// Allocate memory for command array
vector cmdList[5];


for (int i=0; i < cmdCount;i++) {
cmdList[i] = from.cmdList[i];
}

for (int i=0; i < 8; i++) {
strcpy(items[i], from.items[i]);
}

for (int i=0; i < 3; i++) {

resources[i] = from.resources[i];
}

}


The error I get when compiling is:




robot.cpp: In copy constructor 'Robot::Robot(const Robot&)':

robot.cpp:117: error: no match for 'operator=' in 'cmdList[i] = (((command)from->Robot::cmdList) + ((unsigned int)(((unsigned int)i) * 172u)))'
/usr/include/c++/4.4/bits/vector.tcc:156: note: candidates are: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = command, _Alloc = std::allocator]




How would I go about copying vector arrays in a copy constructor?


Answer



In your class, you declare a member variable:



command *cmdList;



But in each of your constructors, you declare a local variable with the same name:



vector  cmdList[5];


In fact, you'll want the type of the member variable to be vector:



//  ROBOT CLASS
class Robot {

private:

std::vector cmdList;

};


Then, in the default constructor, you may allocate memory for it. You don't necessarily have to, depending upon how you later use it.



//  ROBOT CONSTRUCTOR default

Robot::Robot( ) :cmdList(5) {
… // no mention of cmdList in the body required
};


Finally, in the copy constructor, copy it:



//  ROBOT COPY CONSTRUCTOR
Robot::Robot(const Robot &from) : cmdList(from.cmdList) {
… // no mention of cmdList in the body required

}




Alternative: As an alternative, if you choose not to use initialization lists in your constructors, you can do this:

Robot::Robot() {

cmdList = std::vector(5);
// or cmdList.resize(5);


}

Robot::Robot(const Robot &from) {

cmdList = from.cmdList;

}





Extra Credit: If you make the following changes, then you may not need copy constructors at all! Neither will you need destructors or assignment operators:

 class Robot {
private:
std::string name;
int size;

int cmdCount;


std::vector cmdList;
char items[8][16];
int resources[3]; // silver, gold, then platinum

public:
Robot( );
Robot(int num_of_cmds, const char *nm);

const char *get_name( ) { return name.c_str(); }
command get_command(int pos) const { return cmdList[pos]; }

void set_item(const char item[ ], int pos);
const char *get_item(int pos);
};

No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...