Подтвердить что ты не робот

Сделать оператор << виртуальным?

Мне нужно использовать виртуальную < оператор. Однако, когда я пытаюсь написать:

virtual friend ostream & operator<<(ostream& os,const Advertising& add);

Я получаю ошибку компилятора

Ошибка 1 ошибка C2575: 'оператор < <: только функции-члены и базы могут быть виртуальная

Как я могу превратить этот оператор в виртуальный?

4b9b3361

Ответ 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