我对学校的挑战
为class PetData
定义成员函数PrintAll()
,该成员函数按以下方式打印输出。提示:利用基类的PrintAll()
功能。
名称:蓬松,年龄:5,ID:4444
然后,他们将我可以更改的小片段给我下面的代码。之间 // FIXME: Add PrintAll()
成员功能和 /* Your solution goes here */
是我添加的代码,但我没有得到正确的结果。
mycode
// 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
in
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
AnimalData data;
创建了一个新的默认限制AnimalData
,该CC_7与当前PetData
的一部分完全分开。由于您想使用已经拥有的AnimalData
,请丢弃此行,然后从下一行中删除data
。这是事情可能会出错的地方,因此我将直接跳过正确的答案:要获得PrintData
的CC_12函数,您需要明确:
void PrintAll(){
AnimalData::PrintAll();
cout << ", ID: " << idNum;
}
为什么您不能简单地删除data
如果删除对象调用PrintAll
,则data
,
void PrintAll(){
PrintAll();
cout << ", ID: " << idNum;
}
假定 this
。this
是PetData
,对于PetData
,PrintAll
功能的最佳匹配是当前功能。结果是无限递归。
在这里重新使用标识符时要小心要学会的真正教训。在这种情况下,PetData::PrintAll
阴影AnimalData::PrintAll
,在PetData
中替换它。该功能不是virtual
,在这种情况下,您不需要virtual
,因此您不会获得覆盖。您可以轻松而意外地使用功能和变量来执行此操作,从而使程序使用哪一个。
A(可能)更好地构建此程序的方法
利用继承和多态性
#include <iostream>
#include <string>
using namespace std;
class AnimalData
{
public:
virtual ~AnimalData() {}; // with polymorphism you must make sure the
// correct destructor is always called.
// Derived classes will override this
// destructor whether you explicitly define
// them or not.
void SetName(string givenName)
{
fullName = givenName;
}
void SetAge(int numYears)
{
ageYears = numYears;
}
// virtual function. Derived classes can, but do not have to, replace
// this function with a version better suited to the derived class
virtual void PrintAll()
{
cout << "Name: " << fullName;
cout << ", Age: " << ageYears;
}
private:
int ageYears;
string fullName;
};
class PetData: public AnimalData
{
public:
void SetID(int petID)
{
idNum = petID;
}
// Replacing virtual function. Note if the base class function is
// virtual, then child class overrides are automatically virtual
void PrintAll() override // override keyword notifies with a compiler
// error if the function does NOT override when
// it should.
{
AnimalData::PrintAll(); // call base class version for basic data
cout << ", ID: " << idNum; // adding derived class-specific stuff
}
private:
int idNum;
};
// can add WildData here to handle wild animals.
int main()
{
PetData userPet;
userPet.SetName("Fluffy");
userPet.SetAge(5);
userPet.SetID(4444);
userPet.PrintAll();
cout << endl;
// add an vanilla animal for demo
AnimalData generic;
generic.SetName("Fang");
generic.SetAge(7);
generic.PrintAll();
cout << endl;
// demonstrate polymorphism
AnimalData * ptr = & generic;
ptr->PrintAll();
cout << endl;
ptr = & userPet;
ptr->PrintAll(); // runtime calls the correct PrintAll function
cout << endl;
return 0;
}
您似乎对如何调用petdata中的超类动物的方法有一个小小的误解:
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
这创建了类动物数据的新实例,并在该对象上调用printall()。因为在这个新对象中没有初始化的fullname和apeyears,因此您会获得意外的输出。为了调用相同的超类方法,语法为 Superclass::Methodname()
。因此,AnimalData::PrintAll()
的正确版本如下:
void PrintAll(){
AnimalData::PrintAll();
cout << ", ID: " << idNum;
}
这是您的问题。
void PrintAll(){
AnimalData data;
data.PrintAll();
cout << ", ID: " << idNum;
}
此功能创建了AnimalData
类的新对象(将根据默认构造函数构造),然后在该对象上调用AnimalData::PrintAll
方法。您想做的是在上调用AnimalData::PrintAll
方法。对象。
void PrintAll(){
AnimalData::PrintAll(); // call base class method
cout << ", ID: " << idNum;
}
,所以这个比我想象的要简单得多。这确实是从Petdata调用PrintAll方法并附加ID num。
的问题。public void printAll(){
super.printAll();
System.out.print(", ID: " + idNum);
}