Как перегрузить потоковые операторы для работы с функциями, расположенными в разных файлах? - PullRequest
1 голос
/ 30 мая 2019

Я пытаюсь сделать шаблон max функцией (находит наибольшую из трех) для работы с классом, который я создал.

Для этого я должен перегрузить оператор >, и если я хочу отобразить результат функции max, я должен также перегрузить оператор <<.

Если я создаю классв другом файле .h и перегрузке оператора << программа, похоже, не распознает, что перегружен <<.

template <typename X> X max(X a, X b, X c)
{
X maxNum = a;

if( b > maxNum )
    maxNum = b;
if( c > maxNum )
    maxNum = c;

return maxNum;
}

Класс находится в отдельном файле .h.

class Person
{
private:
    std::string Name;
    int Height;
    bool Gender;

public:
    Person() :Name(""), Height(0), Gender(false) {};
    Person(std::string Name, int Height, bool Gender) : Name(Name), 
    Height(Height), Gender(Gender) {};

    void SetName(std::string Name) { this->Name = Name; }
    void SetHeight(int Height) { this->Height = Height; }
    void SetGender(bool Gender) { this->Gender = Gender; }

    std::string GetName() { return Name; }
    int GetHeight() { return Height; }
    bool GetGender() { return Gender; }
};

std::ostream & operator << (std::ostream &MyStream, Person &a)
{
    MyStream << "Name: " << a.GetName() << ", Height: " << a.GetHeight() 
<< ", Gender: " << a.GetGender() << std::endl;
    return MyStream;
}

Основная функция находится в том же файле, что и метод max (не совпадает с классом):

int main()
{
    Person a("Bob", 207, true), b("Alice", 367, false), c("Mickey", 107, 
    true);

    std::cout << max(a,b,c) <<  std::endl;
}

Полученная ошибка:

Error   C2679   binary '<<': no operator found which takes a right-hand 
operand of type 'X' (or there is no acceptable conversion)

Error (active)  E0349   no operator "<<" matches these operands

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

Я хотел бы знать, почему это происходит и есть ли способ обойти это.

1 Ответ

1 голос
/ 30 мая 2019

Вам также необходимо поместить предварительное объявление о перегрузке вашего оператора в заголовочный файл Person, чтобы компилятор распознал его:

std::ostream& operator<<(std::ostream&, Person&);

Также подпись перегруженного оператора должна быть

std::ostream& operator<<(std::ostream&, const Person&);

и функции получения / сравнения соответственно

    std::string GetName() const { return Name; }
    int GetHeight() const { return Height; }
    bool GetGender() const { return Gender; }

    bool operator > (const Person&) const;

Все вещи const необходимы для того, чтобы компилятор имел эти функции (которые не предназначены для изменения Person экземпляр передан) для применения значения r (например, результаты выражений или временных экземпляров).

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