C++ 在派生类之间复制构造函数
如何将派生类复制到另一个派生类 我在术语上有缺陷,所以我将试着用一个例子来说明 我们正在用电脑和人玩纸牌游戏。卡片和命令是其他类C++ 在派生类之间复制构造函数,c++,oop,abstract-class,copy-constructor,C++,Oop,Abstract Class,Copy Constructor,如何将派生类复制到另一个派生类 我在术语上有缺陷,所以我将试着用一个例子来说明 我们正在用电脑和人玩纸牌游戏。卡片和命令是其他类 class Player { Card *Hand[4]; // etc... }; class Human: public Player { Command getCommand(); void PlayCard(Card card); void quit(); // etc... }; class Compute
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.
}
// ...
我们需要删除/释放主目录中的任何内容吗 您可以使用构造函数。对于这种特殊情况,我可能会有一个名为“CopyGameState”的方法。复制构造函数用于将现有对象复制到同一类的新实例中
您需要的是赋值运算符(
运算符=
),它允许将不同类型的值赋值给现有的类对象。它不是复制构造函数,而是转换构造函数。比如:
Computer::Computer(const Player& had_to_go) : Player(had_to_go) {}
p1.quit();
Computer* replacement = new Computer(p1);
delete p1;
p1 = replacement;
这将使用Player
的复制构造函数来保留公共基类中的成员
当然,您最好让Player::Player(constplayer&)
正确地工作,遵循和所有
最后,您将执行以下操作:
Computer::Computer(const Player& had_to_go) : Player(had_to_go) {}
p1.quit();
Computer* replacement = new Computer(p1);
delete p1;
p1 = replacement;
这里有一个设计问题。如果您想在维护公共成员变量的同时将玩家从人切换到计算机,那么您应该以这种方式构造类
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();
这样,卡将被维护,只有控制机制将被更改。好消息:您拼写的“术语”正确:)它是
class
,而不是class
;和public
,而不是public
,这是另一种合理的方法,尽管控制器
可能需要以某种方式读取播放器
的私有数据。在这种情况下,播放器可以公开该数据,也可以让控制器成为播放器的朋友。这就是朋友的作用:)这不仅仅是访问说明符的问题,还需要一个指向实例的指针。但这也很容易解决。@Ben Voigt:是的,刚刚意识到这就是你的意思。我已经将Player ref添加到getCommand调用:-)只需添加一个Player上下文并向控制器传递一个对它的不可变引用。这是完全向后的,因为它不会替换vtable。@Ben-您不能替换构造类的vtable。除非创建一个新对象,否则。。。这就是为什么赋值运算符不是一个好的解决方案。他需要一个新的对象和一个新的vtable。@Ben-他需要重新设计。直到我读了Peter的答案后,我才清楚地理解真正的问题是什么。他希望p1->PlayCard()
开始使用Computer::PlayCard
,而不是Human::PlayCard
,同时保持会员数据的完整性。不管是@Peter的答案还是我的答案都能让他达到目的。你能给我解释一下“三法则”是什么吗:P,也是Player::Player(const-Player&)Player的复制构造函数吗?@Ir-Win:是的,它是Player
的复制构造函数,三法则说如果你有自定义的复制构造函数、赋值运算符或析构函数,你需要这三个。在这种情况下,这是因为播放器
中存储了卡*
。编译器提供的副本将复制指针,这意味着您最终将删除它两次。不好的。在C++-FAQ标签中有一个很好的解释。我将从我的答案中添加一个链接。