c++ - 函数返回类型为父类时,如何返回子类的对象?

标签 c++ c++11 polymorphism

我想 Java 可以用子类的对象代替父类的对象。我想用 C++ 来做。

我正在尝试按照以下方式进行操作。但是,我收到“错误:返回类型‘Food’是一个抽象类”错误。我该如何解决?

它起作用之前:

#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;
}

After 类定义被省略。它不起作用:

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 的智能指针作为我的笔记后发布更新。

最佳答案

您需要按指针类型或对基类的引用返回,而不是按值返回。这是必需的,因为您的基类是一个抽象类,您不能实例化一个抽象类。那就是说你不能只是做

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")

关于c++ - 函数返回类型为父类时,如何返回子类的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44723832/

相关文章:

Haskell 多态树总和

c++ - CERN ROOT 的对象所有权和 C++11 智能指针

c++ - 将重载函数与其多态参数匹配

c++ - C++ 如何检查一个字符串中是否存在多个字母

c++ - QDeclarativeExtensionPlugin 与 QML 通信

c++ - ifstream::ifstream 在目录上的行为是否定义明确?

c++ - 如何使用空终止字符memset char数组?

java - 涉及子类的多态性

c++ - boost::asio 和套接字所有权

c++ - Qt 在 ItemDelegate 之外访问模型数据