如何解决将虚拟类中的对象作为参数传递给函数
我目前正在学习面向对象程序设计,但我充满了疑问:
假设我有一个抽象类Animal。为简化起见,它只有一个虚拟方法,可以说:
class Animal {
public:
virtual string talk() = 0;
}
以及猫和狗类,它们都从抽象类Animal派生而来:
class Cat : public Animal {
public:
string talk(){
return "Meow";
}
}
class Dog : public Animal {
public:
string talk(){
return "Woof";
}
}
我想创建一个Pet类,该类接受一个Dog或Cat作为参数:
class Pet {
public:
Pet(Animal myPet){
this->myPet = myPet;
}
Animal myPet;
}
但是,由于“动物”是一个抽象类,所以我不能这样做。 我该如何解决这个问题?
解决方法
使用参考,如下所示。但是请注意,Pet
的对象本身将具有myPet
,而不是其副本。
class Pet {
public:
Pet(Animal& myPet):myPet{myPet}{
}
Animal& myPet;
}
或使用智能指针(例如std::unique_ptr<Animal>
),如下所示。现在,您可以拥有自己独特的Animal
class Pet {
public:
Pet(std::unique_ptr<Animal>&& myPetP):myPetP{std::move(myPetP)}{
}
std::unique_ptr<Animal> myPetP;
};
然后您可以按如下所示使用它们
int main(){
//with references
Dog d;
Pet p {d};
std::cout << p.myPet.talk();
//with pointers
Pet p {std::make_unique<Dog>()};
std::cout << p.myPetP->talk();
}
,
您不能创建抽象类的实例。您应该使用指针,如下所示:
class Pet {
public:
Pet(Animal* myPet){
this->myPet = myPet;
}
Animal* myPet;
}
,
C ++不允许您将抽象类作为成员变量。甚至非抽象但多态的基类也是有问题的,因为object slicing会导致超出基类被忽略的专业化。
解决此限制的一种方法是改用指针。
class Pet{
public:
Pet(Animal* myPet){
this->myPet = myPet
}
Animal* myPet;
}
在这种情况下,您需要注意析构函数的行为。当Pet类超出范围时,它是否还应该销毁基础的Animal类,还是应该保留下去?根据您期望的行为,您将不得不编写其他的Pet内容。
如果适合您希望Pet展示的所有权行为,您也可以使用诸如std :: unique_ptr之类的智能指针。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。