在指向对象的指针上使用 ostream 重载

Using ostream overloading on pointers to objects

所以,我有一个结构 Bike,它看起来像这样

struct Bike {
    std::string brand;
    std::string model;
    bool is_reserved;

    friend std::ostream& operator<<(std::ostream out, const Bike& b);
};
std::ostream& operator<<(std::ostream out, const Bike& b) {
    return out 
        << "| Brand: " << b.brand << '\n'
        << "| Model: " << b.model << '\n';
}

还有一个 class BikeRentalService,它有一个 std::vector<Bike*> 叫做 bikes_m。这个 class 也有一个方法 print_available_bikes(),它应该迭代所述 std::vector<Bike*> 并使用上面显示的重载 operator<< 打印每个 Bike。这个方法看起来像这样:

void BikeRentalService::print_available_bikes(std::ostream& out) {
    if (bikes_m.empty()) {
        out << "| None" << '\n';
    }
    else {
        for (auto bike : bikes_m) {
            if (!bike->is_reserved) {
                out << bike;
            }
        }
    }
}

问题是使用这个函数只会打印出那些 Bike 对象的地址。在使用 out << 之前取消引用对象也不起作用,Visual Studio 说它不能引用 std::basic_ostream 因为它是 "deleted function"。 将 for 循环写成 (auto *bike : bikes_m) 不会改变任何东西。

重载ostream运算符的正确方法如下:

struct Bike {
    std::string brand;
    std::string model;
    bool is_reserved;

    friend std::ostream& operator<<(std::ostream& out, const Bike& b); // <- note passing out by reference
};
std::ostream& operator<<(std::ostream& out, const Bike& b) {
    return out 
        << "| Brand: " << b.brand << '\n'
        << "| Model: " << b.model << '\n';
}

此外,正如@KyleKnoepfel 所指出的,您也应该将 out << bike; 更改为 out << *bike;