Можно ли каким-либо образом предоставить оператор потока как встроенный в классе (т.е. не являющийся другом)? - PullRequest
2 голосов
/ 06 января 2012

Прежде всего, я хотел бы отметить, что я прочитал решение {предоставлено здесь} , в котором говорится:

Обратите внимание, что операторы выходного потока обычно не являются функциями-членами. (Это потому, что для того, чтобы бинарные операторы были функциями-членами, они должны быть членами типа их левого аргумента. Однако это поток, а не ваш собственный тип. Существует несколько перегрузок оператора << () для некоторые встроенные модули, являющиеся членами класса потока вывода.) </p>

Теперь вот моя проблема. Я удалял библиотеку из большого приложения. Предполагалось, что библиотека должна иметь какие-либо полезные функции, сжатые в заголовочный файл.

Один из классов в этом заголовочном файле должен иметь перегрузку оператора потока <<. Я не могу понять, как сделать это без функции друга, и если я использую функцию друга, я не могу сделать все это в заголовке, потому что я получу несколько ошибок определения. </p>

Итак, есть ли какая-то хитрость - может быть, какая-то игра с функторами, обертками или чем-то еще, которая позволит мне написать определение для перегрузки оператора для << в моем классе, чтобы избежать этой проблемы? </p>

Ответы [ 4 ]

3 голосов
/ 06 января 2012
class SomeClass
{
    friend std::ostream& operator <<(std::ostream& os, SomeClass const& sc)
    {
        // impl
        return os;
    }
};

Определения функций, предоставленные внутри определения класса, неявно помечены inline и, следовательно, не вызовут ошибок компоновщика с несколькими определениями.

В качестве альтернативы, вы можете предоставить определение вне строки и явно пометить его inline, снова избегая ошибок компоновщика с несколькими определениями:

class SomeClass
{
    // unnecessary if operator<< doesn't need access to non-public members
    friend std::ostream& operator <<(std::ostream&, SomeClass const&);
};

inline std::ostream& operator <<(std::ostream& os, SomeClass const& sc)
{
    // impl
    return os;
}
2 голосов
/ 06 января 2012

Если я использую функцию друга, я не могу сделать все это в заголовке, потому что я буду получить несколько ошибок определения.

Отметьте встроенную функцию друга, тогда вы не получите несколько ошибок определения.

1 голос
/ 06 января 2012

Нет, семантика того, как работает перегрузка оператора, помешала бы вам сделать это.

Но нет ничего, что говорило бы, что функция друга не может быть (квалифицирована как) встроенной, в этом случае вы не 'не нужно беспокоиться о множественных определениях: это делает компилятор.

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

0 голосов
/ 06 января 2012

У вас может быть базовый класс с чем-то вроде виртуальной функции-члена void streamout(std::ostream& out) и оператором друга (если вы хотите оставить это в секрете, хотя я не могу придумать причину, почему), который не является членом.Тогда для всех производных классов вам нужно будет реализовать функцию-член, чего вы, похоже, хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...