Сделать оператор << виртуальным?
Мне нужно использовать виртуальную < оператор. Однако, когда я пытаюсь написать:
virtual friend ostream & operator<<(ostream& os,const Advertising& add);
Я получаю ошибку компилятора
Ошибка 1 ошибка C2575: 'оператор < <: только функции-члены и базы могут быть виртуальная
Как я могу превратить этот оператор в виртуальный?
Ответы
Ответ 1
Проблема с этой установкой заключается в том, что оператор < вы определили выше, это бесплатная функция, которая не может быть виртуальной (у нее нет объекта-получателя). Чтобы сделать функцию виртуальной, она должна быть определена как член некоторого класса, что является проблематичным здесь, потому что, если вы определяете оператор < < как член класса, тогда операнды будут в неправильном порядке:
class MyClass {
public:
virtual ostream& operator<< (ostream& out) const;
};
означает, что
MyClass myObject;
cout << myObject;
не будет компилироваться, но
MyClass myObject;
myObject << cout;
будет законным.
Чтобы исправить это, вы можете применить основную теорему разработки программного обеспечения - любая проблема может быть решена путем добавления другого слоя косвенности. Вместо того, чтобы сделать оператор < virtual, подумайте о добавлении новой виртуальной функции в класс, который выглядит следующим образом:
class MyClass {
public:
virtual void print(ostream& where) const;
};
Затем определим оператор < < а
ostream& operator<< (ostream& out, const MyClass& mc) {
mc.print(out);
return out;
}
Таким образом, оператор < свободная функция имеет правильный порядок параметров, но поведение оператора < могут быть настроены в подклассах.
Надеюсь, это поможет!
Ответ 2
Вы определяете свой оператор < < для вызова метода виртуальной печати:
class Base
{
protected:
virtual void print(std::ostream& str) const = 0;
public:
friend std::ostream& operator<<(std::ostream& str, Base const& data)
{
data.print(str);
return str;
}
}
Ответ 3
Похоже, вы действительно хотите предоставить функциональность вывода для иерархии классов, и если это так, вы можете предоставить friend operator <<
, который вызывает функцию virtual
.
class Parent
{
public:
friend std::ostream& operator<< (std::ostream& os, const Parent& p);
// ... other class stuff
protected:
virtual void printMyself(std::ostream& os) const
{
// do something if you must, or make this a pure virtual
}
};
std::ostream& operator<< (std::ostream& os, const Parent& p)
{
p.printMyself(os);
return os;
}
class Child : public Parent
{
// other class stuff...
protected:
virtual void printMyself(std::ostream os) const
{
// whatever you need to do
}
};
Также подробно описано в часто задаваемые вопросы по С++
Ответ 4
Метод, который я использую, функционально идентичен тому, что упомянули другие, за исключением того, что я делаю виртуальную функцию "print" функцией-функцией-членом функции >>
:
class my_class
{
protected:
virtual std::ostream& operator>>(std::ostream& os_) const
{
// print *this to `os_`
return os_;
}
public:
friend inline std::ostream& operator<<(std::ostream& os, const my_class& mc) {
return (mc >> os);
}
};
Это идея шаблона утилиты из одного из моих проектов с открытым исходным кодом. См.: https://libnstdcxx.googlecode.com/svn/trunk/doc/html/classnstd_1_1basic__printable.html