Итак, я попытался создать программу в соответствии с заголовком этого вопроса, и мой код соответствует только первому.

Вот код

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Distance {
    int feet;
    int inches;
    string display();

 public:
    Distance();
    Distance(int, int);
    Distance operator+(Distance);
    friend string operator<<(ostream&, Distance);
    friend string operator<<(string, Distance);
    friend string operator<<(Distance, Distance);
};

Distance::Distance() {
    feet = 0;
    inches = 0;
}

Distance::Distance(int feet, int inches) {
    this->feet = feet;
    this->inches = inches;
}

string Distance::display() {
    stringstream str;
    str << feet << '\'' << inches << '\n';
    return str.str();
}

string operator<<(ostream& os, Distance distance) {
    string out = distance.display();
    os << out;
    return out;
}

string operator<<(string str, Distance distance) {
    return (str + distance.display());
}

string operator<<(Distance distance1, Distance distance2) {
    return distance1.display() + distance2.display();
}

int main() {
    Distance distance(5, 8);
    Distance distance2(5, 9);

    cout << distance << distance2;
}

Я пробовал несколько способов, и один из них сработал: если я поставлю скобки в этой строке cout, например, cout << (distance << distance2);, тогда все будет нормально!

Но я хочу, чтобы это работало без скобок, как вы знаете, как мы это делаем со строками cout << "abc" << "def"; Теперь я не знаю, возможно ли это вообще с объектами.

Вот несколько скриншотов вывода

Без скобок ↴ cout << distance << distance2;

without brackets

В скобках ↴ cout << (distance << distance2);

with brackets

Если невозможно получить тот же результат, что и при использовании скобок, без использования скобок, может кто-нибудь, дайте мне знать, как это работает со строками? как будто мы не ставим скобки со строками, но все равно отображается целиком.

cout << "abc" << "def";

Вывод: "abcdef"

0
anon 2 Июл 2021 в 17:35

3 ответа

Лучший ответ

Обычное дело - просто иметь одну перегрузку.

//This requires a friend declaration inside the class first.
std::ostream& operator<<(std::ostream& os, const Distance &distance) {
    return os << distance.feet << '\'' << distance.inches << '\n';
}

Это позволяет связать как ожидалось:

std::cout << 3 << myDistance << myDistance << "hi!"
3
Remy Lebeau 2 Июл 2021 в 14:41

Для поддержки цепочки operator<<(ostream&, Distance) необходимо вернуть заданный ostream&, а не string. Кроме того, Distance следует передавать по константной ссылке:

ostream& operator<<(ostream& os, const Distance &distance) {
    os << distance.display();
    return os;
}

operator<<(string, Distance) и operator<<(Distance, Distance) просто не имеют смысла иметь, поэтому их следует удалить полностью.

3
Remy Lebeau 2 Июл 2021 в 14:47

Вы неправильно реализовали operator<<(ostream&, Distance).

Поскольку он возвращает string, строка:

cout << distance << distance2;

Сначала оценивает cout << distance, а затем решает ...

{temporary std::string} << distance2;

... который, конечно, больше ничего не печатает.

Вместо этого функция должна возвращать ссылку на параметр left .

ostream& operator<<(ostream& os, Distance distance) {
    string out = distance.display();
    os << out;
    return os;
}
1
Drew Dormann 2 Июл 2021 в 14:43