Копировать конструктор между производными классами - PullRequest
2 голосов
/ 22 июля 2011

Как скопировать производный класс в другой?

У меня терминологический недостаток, поэтому я попытаюсь проиллюстрировать это примером.

Мы играем в карточную игру с компьютерным игроком и человеком-игроком. Card и Command - это другие классы.

class Player
{
    Card *Hand[4];
    // etc...
};

class Human: public Player
{
    Command getCommand();
    void PlayCard(Card card);
    void quit();
    // etc...
};

class Computer: public Player
{
    Command ai();
    void PlayCard(Card card);
    // etc...
};

И где-то в основной функции мы имеем ...

// ...
Human p1; // Assume initialized and usable.
if(p1.getCommand() == QUIT)
{
    cout << "PLAYER 1 RAGEQUITS WHAT A NOOB LOL << endl;
    cout << "A COMPUTER WILL NOW TAKE OVER." << endl;
    p1.quit()
    p1 = new Computer(); // THE IDEA BEING THAT WE WANT TO PRESERVE p1's MEMBERS.
}
// ...

То, что я пытаюсь сделать, - это преобразовать p1 в «компьютер», сохраняя при этом состояние его членов.

Мы используем конструктор копирования для этого? Если нет, какие методы вы используете?

РЕДАКТИРОВАТЬ: Это способ использования оператора присваивания?

Computer& Human::operator=(const Human &h) // Assignment operator
{
    Hand = h.Hand;
    member2 = h.member2;
    member3 = h.member3;
    ...

    return *this;
}

Нужно ли удалять / освобождать что-либо в основном?

Ответы [ 4 ]

5 голосов
/ 22 июля 2011

У вас есть проблема дизайна здесь. Если вы хотите переключить игрока с человека на компьютер, сохраняя общие переменные-члены, вам следует структурировать свои классы таким образом.

class Player
{ 
public:
    friend class Human;    // These friends are necessary if the controllers
    friend class Computer; // need access to Player's private data.

    Card hand[4];
    Controller* controller;
};

class Controller
{
public:
    virtual Command getCommand(Player const&) = 0;
};

class Human : public Controller
{
public:
    Command getCommand(Player const&) { /* get command from user input */ }
};

class Computer : public Controller
{
public:
    Command getCommand(Player const&) { /* get command from AI */ }
};

Затем, когда вам нужно переключиться с человека на компьютер, просто смените контроллер.

p1->controller = new Computer();

Таким образом, карты будут сохраняться, будет изменен только механизм управления.

2 голосов
/ 22 июля 2011

Конструктор копирования используется для копирования существующего объекта нового экземпляра того же класса.

Вам нужен оператор присваивания (operator=), который позволяет присваивать значение другого типа вашему существующий объект класса.

2 голосов
/ 22 июля 2011

Это был бы не конструктор копирования, а конструктор преобразования. Что-то вроде:

Computer::Computer(const Player& had_to_go) : Player(had_to_go) {}

Это будет использовать конструктор копирования Player для сохранения членов в общем базовом классе.

Конечно, вам лучше заставить Player::Player(const Player&) работать правильно, следуя "правилу трех" и всем.

В конце концов, вы бы сделали что-то вроде:

p1.quit();
Computer* replacement = new Computer(p1);
delete p1;
p1 = replacement;
2 голосов
/ 22 июля 2011

Вы можете использовать конструктор.Для этого конкретного случая у меня, вероятно, был бы метод, называемый что-то вроде «CopyGameState».

...