C++ Vector Arrays in Copy Constructors

Go To StackoverFlow.com

0

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 <command> 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 <command> 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?

2012-04-03 21:23
by 0x01
Why don't you just use a std::vector<command> as a member of the class and let it deal with copying (and std::string for the robot name)? The rule of thumb for copy constructors is that, unless you're writing a class whose single aim is to manage a resource, if you need to write them you're probably doing something wrong - Matteo Italia 2012-04-03 21:26
"Allocate memory for command array" .. nope, you just created a local which shadows the member variable - Karoly Horvath 2012-04-03 21:27


5

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 <command> cmdList[5];

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

//  ROBOT CLASS
class Robot {
    private:
…
        std::vector<command> 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<command>(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<command> 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);
};
2012-04-03 21:28
by Robᵩ
Thank you, that fixed it. And the assignment its for specifically requests this format but I will have to remember this for future problems - 0x01 2012-04-03 22:43