Можно ли сделать виртуальным оператор >>?
Можно ли в абстрактном базовом классе сделать виртуальным оператор вывода <<, чтобы в дальнейшем переопределить его в наследниках? Пока что сделал так. Базовый класс:
class Pair
{
private:
long int first;
int second;
public:
friend virtual std::ostream& operator << (std::ostream& out_str, Pair& to_out) = 0;
};
Наследник:
class Money: public Pair
{
public:
friend std::ostream& operator << (std::ostream& out_str, Pair& to_out) override;
Компилятор ругается на override, считает что нужна точка с запятой.
Ответы (3 шт):
Оператор <<, как и любой другой нестатический метод класса, можно сделать виртульным. Однако такая форма оператора << принимает экземпляр класса в качестве неявного первого аргумента:
class base
{
public: virtual base &
operator <<(int x) = 0;
};
class derived: public base
{
public: base &
operator <<(int x) override
{
return *this;
}
};
А запись вида std::ostream& operator << (std::ostream& out_str, Pair& to_out) служит для объявления свободной функции двух аргументов.
Напрямую нельзя, потому что friend создает обычную функцию, а не метод.
Нужно вынести содержимое operator<< в метод, который потом переопределять:
virtual void Print(std::ostream &out_str) const = 0;
friend std::ostream &operator<<(std::ostream &out_str, Pair &to_out)
{
to_out.Print(out_str);
return out_str;
}
Можете делать, например, так:
class Pair
{
protected:
long int first;
int second;
virtual std::ostream& put(std::ostream& os) const
{
os << first << ' ' << second;
return os;
}
public:
Pair(long int a = 0, int b = 0) : first(a), second(b) {}
friend std::ostream& operator << (std::ostream& out_str, const Pair& to_out)
{
return to_out.put(out_str);
}
};
class Money : public Pair
{
public:
Money(const int a, const int b) : Pair(a, b) {}
protected:
virtual std::ostream& put(std::ostream& os) const override
{
os << first << " dollar, " << second << " cent\n";
return os;
}
};
То есть для всех Pair и его производных оператор просто вызывает виртуальную функцию, которая переопределена где нужно.
int main()
{
Pair p(2, 4);
Money m(23, 34);
cout << m << p;
return 0;
}