我猜Java可以将子类的对象替换为父类的对象。我想用c ++做。
我正在努力做到如下。但是,我得到了“错误:返回类型'食物'是一个抽象类”错误。我该如何解决?
之前它有效:
#include <iostream>
using namespace std;
class Food {
public:
virtual void SetPrice(int myprice) = 0;
int GetPrice() {
return price;
}
protected:
int price;
};
class Fruit : public Food {
public:
void SetPrice(int myprice) {
price = myprice - 20;
}
};
class Fish : public Food {
public:
void SetPrice(int myprice) {
price = myprice / 2;
}
};
int main(int argc, char* argv[])
{
Food *pFood;
Fruit myFruit;
Fish myFish;
if (strcmp(argv[1], "fruit") == 0) {
pFood = &myFruit;
} else {
pFood = &myFish;
}
pFood->SetPrice(100);
cout << pFood->GetPrice() << endl;
return 0;
}
省略类定义后。它不起作用:
Food getFoodObject(string type)
{
if (strcmp(type, "fruit") == 0) {
Fruit myFruit;
return &myFruit; // I don't want to write 2 lines. I want to return the above line. This is my another question...
}
Fish myFish;
return &myFish;
}
int main(int argc, char* argv[])
{
Food *pFood;
pFood = getFoodObject(argv[1])
pFood->SetPrice(100);
cout << pFood->GetPrice() << endl;
return 0;
}
更新1
感谢许多建议,我的问题已经解决了。我需要使用c ++ 11,所以我使用unique_ptr而不是make_unique。
std::unique_ptr<Food> getFoodObject(string type)
{
if (type == "fruit") {
return std::unique_ptr<Fruit>(new Fruit);
}
return std::unique_ptr<Fish>(new Fish);
}
int main(int argc, char* argv[])
{
std::unique_ptr<Food> pFood = getFoodObject(argv[1]);
pFood->SetPrice(100);
cout << pFood->GetPrice() << endl;
return 0;
}
@dlasalle提到了Boost库。我可以使用Boost的智能指针作为我的笔记后发布更新。
答案 0 :(得分:2)
在Java中,你总是返回一个引用(一个美化指针),但是在C ++中你可以选择按值,引用或指针返回对象。 C ++中的多态性只能通过引用和指针来实现。
通过按值返回父类,最终得到object slicing,但最终还是得到了一个抽象类的实例,该实例无效(因此编译器错误)。
你想做这样的事情:
#include <memory>
std::unique_ptr<Food> getFoodObject(string type)
{
std::unique_ptr<Food> ptr;
if (type.compare("fruit") == 0) {
ptr.reset(new Fruit());
} else {
ptr.reset(new Fish());
}
return ptr;
}
如果您不使用c ++ 11,则需要使用boost的智能指针或简单的原始指针。
答案 1 :(得分:1)
您需要通过指针类型或对基类的引用返回,而不是按值返回。这是必需的,因为您的基类是一个抽象类,您无法实例化一个抽象类。那说你可以做到
Food* getFoodObject(string type)
{
if (strcmp(type, "fruit") == 0) {
Fruit myFruit;
return &myFruit; // I don't want to write 2 lines. I want to return the above line. This is my another question...
}
Fish myFish;
return &myFish;
}
因为那时你正在返回一个指向函数本地对象的指针,一旦函数退出,对象就会被销毁,留下一个悬空指针。我们可以做的是更改代码以使用std::unique_ptr
(使用智能指针,因为它为我们管理内存),然后你可以有类似的东西
std::unique_ptr<Food> getFoodObject(string type)
{
if (type == "fruit") {
return std::unique_ptr<Fruit>(new Fruit);
// or in C++14 return std::make_unique<Fruit>();
}
return std::unique_ptr<Fish>(new Fish);
// or in C++14 return std::make_unique<Fish>();
}
您可以将此功能称为
int main(int argc, char* argv[])
{
std::unique_ptr<Food> pFood = getFoodObject(argv[1])
pFood->SetPrice(100);
cout << pFood->GetPrice() << endl;
return 0;
}
另请注意,if (strcmp(type, "fruit") == 0)
无效。 strcmp
处理的是c字符串,而不是std::string
。要比较std::string
,您可以==
使用if (type == "fruit")
答案 2 :(得分:1)
您可以在c ++中使用指针。无法实例化抽象类,因此您不能将抽象基类用作实例。您可以创建父具体类,然后使用设置基类的指针。