0

I'm writing a C++ program involving polymorphism. I need to overload the operators "<<" and ">>" as friend functions. I have the base class base and 3 derived classes: der1,der2,der3 and a pointer to the base class * p. If I declare the functions as

istream &operator>>(istream &i,der1 &d1) {...}
istream &operator>>(istream &i,der2 &d2) {...}
istream &operator>>(istream &i,der3 &d3) {...}

and call them like

base *p;
p=new der1;
cin>>p;

the program doesn't compile as there's no function with a base parameter. But if I declare it so,it doesn't make any difference if the actual object is of type der1,der2 or der3,although I want it to behave differently depending on the type of the object. All I could think of was to create a virtual function in base and override it the inherited classes. But thus,I'll have to call the functions as

*p>>cin

which doesn't look so natural. How can I solve the problem?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
flaviumanica
  • 195
  • 1
  • 4
  • 14
  • Well you declare 3 functions to take references and then you call one using a pointer; that will be a different function to begin with. And yes, the C++ run time cannot see whether your base pointer points to a derived -- polymorphism depends on the "calling object", not on the argument objects. if you say `p->f()` the code in *p will know what to call, but in `::f(p)` there is no code which introspects *p and decides which f to call. That decision is made at compile time basd on the static tye of p. – Peter - Reinstate Monica Apr 17 '15 at 13:06
  • Have you tried `cin>>(*p)`? You are passing a pointer to an operator expecting a reference. – user2891462 Apr 17 '15 at 13:07

3 Answers3

4

Don't try to make the operator>> a member. You can't and still keep cin on the left side. Just make it a free function and have it call a member (which can then be virtual):

struct base { virtual void read(istream &i); };

istream &operator>>(istream &i,base &b) {b.read(i); return i;}
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
2

You can create an operator>> for base class:

istream &operator>>(istream &i, base *b) {
    b->ReadFromIstream(i);
    return i;
}

Then you make the ReadFromIstream a virtual function, and overload it from the derived classes. This way you have the same syntax cin >> p, and they behave differently according to the type of p.

Ying Xiong
  • 4,578
  • 8
  • 33
  • 69
0

I think you have phantasies about the C++ runtime abilities :-). The C++ run time cannot (or chooses not to) see whether your base pointer argument points to a derived -- polymorphism depends on the "calling object", not on the argument objects. if you say p->f() the code in *p will know what to call, but in ::f(p) there is no code which introspects *p and decides which f to call. That decision is made at compile time based on the static type of p.

That said, the workaround is the strategy described by @DarkFalcon. Call virtual methods of the object from the function.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62