简体   繁体   中英

C++: friend function, derived class

I've got 2 classes, base class is "Port" and derived class is "VintagePort". As far as I know If i use reference or pointer of base class to object of derived class, it automatically finds correct method, not for reference or pointer but exactly to object(if methods are virtual).

In my situation you can see both classes have friend function "operator<<". But it looks like when I'm using pointer for base class, it calls function only from base class. If I use "cout << VintagePort" It works ok. My question: Is it working correctly or I should fix something in code?

std::ostream& operator<<(std::ostream& os, const Port& p)
{
os << p.brand << ", " << p.style << ", " << p.bottles << endl;
return os;
}

std::ostream& operator<<(std::ostream& os, const VintagePort& vp)
{
os << (const Port &) vp;
cout << ", " << vp.nickname << ", " << vp.year << endl;
return os;
}




VintagePort vp1;
VintagePort vp2("Gallo", "lekko brazowy", 50, "Blaze", 1990);
VintagePort vp3(vp2);

Port* arr[3];
arr[0] = &vp1;
arr[1] = &vp2;
arr[2] = &vp3;

for (int i = 0; i < 3; i++)
{
    cout << ">>>>> " << i+1 << " <<<<<" << endl;
    cout << *arr[i];   // call for base class instead derived class
    arr[i]->Show();    
}

The compiler doesn't now the pointer actually points to an inherited class. One way to solve this is to have a virtual function in the base class for output, and override it in the class inheriting the base class. Then call this virtual method in the output operator.

In C++ polymorphism can only be achieved by means of virtual functions, and operator<< is not one (and cannot be for your purposes, since the first argument is the std::ostream . If you need this sort of behavior, the simple approach is providing a virtual print function in your hierarchy, and have operator<< forward the call performing dynamic dispatch:

struct base {  // Don't forget virtual destructors
   virtual void print( std::ostream& ) const;
};
struct derived : base {
   virtual void print( std::ostream& ) const;
};
std::ostream& operator<<( std::ostream& o, const base& b ) {
   b.print( o );
   return o;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM