2015-04-27 2 views
0

Как вы можете видеть, в обоих случаях вызывается только перегруженная версия оператора вставки потока для базового класса. Я понимаю, почему это так. Это связано с тем, что динамическая привязка отсутствует. Но как я могу это исправить?Перегрузка верхнего уровня и потокового оператора

#include <iostream> 

using namespace std; 

class A { 
    int i; 
    char c; 
public: 
    A(int i = 0, char c = ' ') { 
     this->i = i; 
     this->c = c; 
    } 
    int getI() { return i; } 
    char getC() { return c; } 
    friend ostream& operator << (ostream&, A&); 
}; 

class B : public A { 
    double d; 
public: 
    B(int i = 0, char c = ' ', double d = 0.0) : A(i, c), d(d) {} 
    friend ostream& operator << (ostream&, B&); 
}; 

ostream& operator << (ostream& out, A& a) { 
    out << "\nInteger: " << a.i << "\nCharacter: " << a.c << endl; 
    return out; 
} 

ostream& operator << (ostream& out, B& b) { 
    out << "\nInteger: " << b.getI() << "\nCharacter: " << b.getC() << "\nDouble: " << b.d << endl; 
    return out; 
} 

int main() { 
    A* a = new A (10, 'x'); 
    B* b = new B(20, 'y', 5.23); 
    A* array[] = { a, b }; 
    cout << *(array[0]); 
    cout << "\n______________________________\n"; 
    cout << *(array[1]); 
    delete a; 
    delete b; 
    cin.get(); 
    return 0; 
} 

Как я могу сделать cout << *(array[1]); вызов перегруженной поток вставки оператора, который принимает объект B, как один из его аргументов?

+0

возможно дубликат [Есть ли перегрузка сделать приведение к базовому типу операторов потока (<< && >>) следует обязательно перегружен, как функции-члены и не друзья функций?] (Http://stackoverflow.com/questions/29885965/does-upcasting- make-overloading-the-stream-operator-be-обязательно-o) – phantom

+0

Итак, где же решение? – User2k14

ответ

1

Вы не можете заставить его вызвать перегруженный оператор, так как перегрузка разрешена во время компиляции.

Чтобы выполнить разрешение во время выполнения, то есть использовать динамическую отправку, вам необходимо переместить код, который выполняет печать, в виртуальную функцию-член.
Затем вызовите это от оператора (вам нужен только один, для базового класса).

class A 
{ 
    public: 
    // ... 
    // Override this in B 
    virtual void print(std::ostream& o) const 
    { 
     o << "\nInteger: " << i << "\nCharacter: " << c << endl; 
    } 
    // ... 
}; 

ostream& operator << (std::ostream& out, const A& a) { 
    a.print(out); 
    return out; 
} 
Смежные вопросы