重载输入运算符以确定要生成哪种派生类?

时间:2013-11-26 23:04:36

标签: c++ pointers operator-overloading overloading

我有一个名为Animal.h的基类

在那里,我有纯虚拟方法来描述动物所产生的噪音,这种方法会被衍生类(例如Cat / Dog)覆盖(在它们自己的头文件中)。

我有一个主类来调用函数并打印出与这些类相关的不同内容。

我正在尝试重载我的Animal.h类中的输入操作符,让我读入一个输入并根据输入的内容创建Animal类。

E.g。 (在我的主要内容):

Animal *a = (animal*) 0;
while (read_animal(cin, a) && a)
    cout << *a << ’\n’;

在我的Animal.h中:

friend istream &operator >>( istream &input, animal* &animal_type )
{
    string in;
    getline(input, in);

    if (in.find("Cat") != std::string::npos)
    {
        *animal_type = new Cat();
    }
    return input;
}

但intellisense告诉我:

错误3错误C2061:语法错误:标识符'Cat'

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

你有一个循环依赖。在定义基类Cat之前,您无法定义Animal类,并且Animal::operator>>的定义取决于Cat

您需要将operator>>拆分为两部分,头文件中的声明和包含正文的源。在源代码中,您可以添加定义AnimalCat的标头。

答案 1 :(得分:0)

原始问题:

  

错误3错误C2061:语法错误:标识符'Cat'

您的编译器不知道Cat是什么 您是否包含了相应的头文件。

但我不会这样做。

您的操作取决于指针。这意味着你在没有所有权语义的情况下传递指针。这会导致各种各样的问题。如果您需要动态创建不同的类型,我将拥有一个知道如何创建不同类型的特定类的管理类型。

我会创建一个工厂(这描述了上面的关系(但还有其他技术)),它首先读取类型。然后创建一个适当的对象并用流初始化它。

class AnimalFactory
{
    public:
        static std::unique_ptr<Animal> deserializeAnimal(std::istream& str)
        {
              // 1 Detect the correct animal type.
              str ????

              // 2 Create the correct object.              
              std::unique_ptr<Animal>  result(new XXXX); // or constructor takes a stream?
                                     // how you decide XXXX depends a lot on other parts of
                                     // the system.

              // 3 use the input operator to initialize it.
              str >> (*result);      // unless you already did this with the constructor.

              return result;
        }
};