c++ - C++ 重载基类的>> 运算符

  显示原文与译文双语对照的内容
56 5

所以我有一个基类动物,它继承了 2个类,它们是 cat 和 dog 。这两个类重定义一个纯虚方法说的只是 couts"meow",cat 和"宽度"的。在我的主要功能中,我希望能够做这样的事情:

int main (void) {
 Animal a;
 dog d;
 while (cin>> a)//is this even possible? would it be cin>> d; instead?
 cout <<a <<endl;
 return(0);
}

所以这应该会让动物说函数,但是我怎么才能这么做?还有,如果你不知道用户要用到的是什么类型的动物,你会怎么决定使用哪个功能?

时间:原作者:0个回答

90 5

在基类中执行类似的操作:

#include <istream>
using namespace std;
class Animal
{
 friend istream & operator>> ( istream &is, Animal &animal )
 {
 animal.readFromStream(is);
 return is;
 };
protected:
 virtual void readFromStream( istream &is ) = 0;
};

并在派生中:

class Dog : public Animal
{
 protected:
 virtual void readFromStream( istream &is )
 {
//read dog
 };
};
原作者:
69 1

下面是重写 operator<<的一个示例,它调用 public 成员函数 speak()如果需要访问重载 operator<< 中的private 成员,请将它的设为 friend

#include <iostream>
class Animal {
 public:
 virtual std::string speak(void) = 0;
};
class Dog : public Animal {
 std::string speak() { return"woof"; }
};
class Cat : public Animal {
 std::string speak() { return"meow"; }
};
std::ostream& operator<<(std::ostream& out, Animal& a) {
 out <<a.speak();
 return out;
}
int main (void) {
 Dog d;
 Cat c;
 Animal &a = d;
 std::cout <<a <<std::endl;
 Animal &a2 = c;
 std::cout <<a2 <<std::endl;
 return 0;
}

你应该能够了解如何为 operator>> 做类似的事情。

还有,如果你不知道用户要用到的是什么类型的动物,你会怎么决定使用哪个功能?

这就是动态绑定/多态性背后的思想。java和 a2 是对 Animal 派生类型的引用,因为 speak() 是虚拟的,因此 a 表将包含一个指向 Dog 或者 Cat 对象所必需的speak() 函数的指针。

原作者:
147 3

你不能精确地做你想要的。就是,你不能

Animal a;
std::cin>> a;

希望'a'的类型能够改变。基本上,对象不是多态的--指针,引用是多态的。

你可以根据需要做一些类似你想要的东西:

Animal* pA;
std::cin>> pA;
std::cout <<*pA <<"n";
delete pA;

你可以通过重载来实现

istream& operator>>(istream&, Animal*&);

若要创建( 通过 new ),则运行时指示类型的对象。

请考虑以下程序:

#include <iostream>
class Animal {
public:
 virtual void speak(std::ostream& os) const = 0;
 virtual ~Animal() {}//must be virtual
};
class Dog : public Animal {
public:
 void speak(std::ostream& os) const { os <<"woof"; }
};
class Cat : public Animal {
public:
 void speak(std::ostream& os) const { os <<"meow"; }
};
std::ostream& operator<<(std::ostream& os, const Animal& being) {
 being.speak(os);
 return os;
}
std::istream& operator>>(std::istream& is, Animal*& zygote) {
 std::string species;
 is>> species;
//fetch remainder of line with std::getline()
 if(species =="cat") {
//parse remainder of line
//Finally, create a Cat
 zygote = new Cat;
 return is;
 }
 if(species =="dog") {
//parse remainder of line
//and create a Dog
 zygote = new Dog;
 return is;
 }
//Hmm, unknown species? Probably not safe to create
 std::cerr <<"Warning! Unknown species. Could be dangerous!n";
 is.setstate(std::ios::failbit);
 zygote = 0;
 return is;
}
int main () {
 Animal *pPet;
 while(std::cin>> pPet) {
 std::cout <<*pPet <<"n";
 delete pPet;
 }
}
原作者:
...