我要说的学校面临挑战
为类PetData定义一个成员函数PrintAll(),该函数按如下所示输出输出。提示:利用基类的PrintAll()函数。
名称:蓬松,年龄:5,ID:4444
然后,他们给我下面的代码,并提供了一个可以更改的小片段。之间 // FIXME:添加PrintAll()成员函数 和 / *您的解决方案在这里* / 是我添加的代码,但没有得到正确的结果。
我的代码
// FIXME: Add PrintAll() member function
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
/* Your solution goes here */
完整代码
#include <iostream>
#include <string>
using namespace std;
class AnimalData {
public:
void SetName(string givenName) {
fullName = givenName;
};
void SetAge(int numYears) {
ageYears = numYears;
};
// Other parts omitted
void PrintAll() {
cout << "Name: " << fullName;
cout << ", Age: " << ageYears;
};
private:
int ageYears;
string fullName;
};
class PetData: public AnimalData {
public:
void SetID(int petID) {
idNum = petID;
};
// FIXME: Add PrintAll() member function
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
/* Your solution goes here */
private:
int idNum;
};
int main() {
PetData userPet;
userPet.SetName("Fluffy");
userPet.SetAge (5);
userPet.SetID (4444);
userPet.PrintAll();
cout << endl;
return 0;
}
我得到的结果
名称:,年龄:-502747520,ID:4444
我想要的结果
名称:蓬松,年龄:5,ID:4444
答案 0 :(得分:3)
在
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
AnimalData data;
创建一个默认初始化的新AnimalData
,它与作为当前AnimalData
一部分的PetData
完全分开。由于您想使用已有的AnimalData
,因此请舍弃此行,并从下一行删除data
。这是可能会出错的地方,因此我将直接跳到正确的答案:要获得PrintData
的{{1}}函数,您需要明确:
AnimalData
void PrintAll(){
AnimalData::PrintAll();
cout << ", ID: " << idNum;
}
如果删除对象以在data
上调用PrintAll
data
假定为 void PrintAll(){
PrintAll();
cout << ", ID: " << idNum;
}
。 this
是this
,对于PetData
,PetData
函数的最佳匹配是当前函数。结果是无限recursion。
在这里要学习的实际课程是在重用标识符时要小心。在这种情况下,PrintAll
会遮盖PetData::PrintAll
,并在AnimalData::PrintAll
内部将其替换。该函数不是PetData
,在这种情况下,您不需要virtual
,因此不会覆盖。您可以通过函数和变量轻松,意外地执行此操作,从而导致程序正在使用哪个函数。
充分利用继承和多态性
virtual
答案 1 :(得分:1)
您似乎对如何在PetData中调用超类AnimalData的方法有一个小小的误解:
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
这将创建类AnimalData的新实例,并在该对象上调用PrintAll()。因为fullName和ageYears不在此新对象中初始化,所以您会得到意外的输出。要调用超类的相同方法,语法为Superclass::Methodname()
。因此,AnimalData::PrintAll()
的正确版本如下:
void PrintAll(){
AnimalData::PrintAll();
cout << ", ID: " << idNum;
}
答案 2 :(得分:1)
这是你的问题。
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
此函数创建类AnimalData
的新对象(将根据默认构造函数构造),然后在该对象上调用AnimalData::PrintAll
方法。您想要做的就是在 this 对象上调用AnimalData::PrintAll
方法。
void PrintAll(){
AnimalData::PrintAll(); // call base class method
cout << ", ID: " << idNum;
}
答案 3 :(得分:0)
所以这个比我想象的要简单得多。确实是从PetData调用printAll方法,并附加ID num。
public void printAll(){
super.printAll();
System.out.print(", ID: " + idNum);
}