user13756099
user13756099

Reputation:

Implementing copy c'tor with shared pointer?

Since my last question caused a lot of confusion I'm completely going to rewrite it with more info.

I have an abstract class Character which is being inherited by Soldier and Medic I wrote another class called Game to manage a game board similar to chess game, it has the following objects:

    mtm::Dimensions dimensions;
    std::vector<std::shared_ptr<Character>> board;

Note previously I had std::vector<Character*> board; But was told by you that it's bad and I need to use smart pointers, while unique_ptr suits my code more but my professor wants me to use only shared_ptr.

The problem is that I don't know how to implement the copy c'tor. I wrote:

Game::Game(const Game &other): dimensions(other.dimensions), board(dimensions.getRow()*dimensions.getCol()) {
    int board_size= dimensions.getRow()*dimensions.getCol();
    for (int i=0;i<board_size;++i)
    {
        this->board[i]=other.board[i];
    }
}

But it seems wrong and too much (as I was told by you). Any help?

Note: when I copy a game I don't want to have 2 games which share some pointers but spitted games so I could change one but not to affect the other.

Upvotes: 1

Views: 66

Answers (1)

Slava
Slava

Reputation: 44238

You need to make a copy of each Character object, for non abstract class without hierarchy this would be :

Game::Game(const Game &other): dimensions(other.dimensions) 
{
    board.reserve( other.board.size() );
    for( const auto &pch : other.board )
       board.push_back( std::make_shared( *pch ) );
}

assuming, that Character has proper copy ctor as well and it is not a pointer to base class which could be inherited.

In your case as it is abstract class and you point to derived ones you have to add pure virtual method clone() that returns std::shared_ptr<Character> to Character class and override it in every derived one:

class Character ... {
public:
    virtual std::shared_ptr<Character> clone() const = 0;
    ...
};

Then Game copy ctor would be:

Game::Game(const Game &other): dimensions(other.dimensions) 
{
    board.reserve( other.board.size() );
    for( const auto &pch : other.board )
       board.push_back( pch->clone() );
}

Upvotes: 3

Related Questions