重载运算符“<<”,无输出流意图

Overload operator '<<' without output streaming intentions

我是运算符重载的新手,我正面临这个挑战:

我有这个 class Ticket,我正在创建 2 个对象 Ticketticket1ticket2。每张票都有一些手提箱,我将这些 id 存储到一个名为 id_suitcases.

的向量中

现在我希望能够使用运算符 <<

将多个 suitcaseID 添加到该向量

例如

输出:

19/20 NORMAL
Xico da Tina | Passaport: 2511 | Company: TAP
Suitcases: 120  20  35  50

Jussara Barlabe | Passaport: 7471231 | Company: Jato do Bob
Suitcases: 120  20  35  50

像这样使用运算符<<

ticket1 << 455 << 73 <<  9;
ticket2 <<  55 << 83 << 32;

输出:

After add suitcases to passenger
Xico da Tina | Passaport: 2511 | Company: TAP
Suitcases: 120  20  35  50  455  73  9

Jussara Barlabe | Passaport: 7471231 | Company: Jato do Bob
Suitcases: 120  20  35  50  55  83  32

Class 门票

class Ticket {
    std::string passenger;
    int passport;
    std::string& company;
    std::vector<int> id_suitcases;
public:

    Ticket(std::string cliente, int passId, std::string& comp, std::vector<int> suitcases) :company(comp)
    {
        passenger = cliente;
        passport = passId;
        id_suitcases = suitcases;
    }

    friend std::ostream& operator << (std::ostream& output, const Ticket& b)
    {
        output << b.passenger << " | Passaport: " << b.passport << " | Company: " << b.company << std::endl;
        output << "Suitcases: ";
        for (auto suitcase : b.id_suitcases)
            output << suitcase << "  ";
        return output;
    }

    bool operator << (int suitcaseID)
    {
        for (auto suitcase : id_suitcases)
            if (suitcaseID == suitcase)
            {
                return false;
            }
        id_suitcases.push_back(suitcaseID);
        return true;
    }
};

主要

int main()
{
    std::cout << "19/20 NORMAL\n";
    std::vector<int> suitcases;
    suitcases.push_back(120);
    suitcases.push_back(20);
    suitcases.push_back(35);
    suitcases.push_back(50);

    std::string company1 = "TAP";
    std::string company2 = "Jato do Bob";

    Ticket ticket1("Xico da Tina", 2511, company1, suitcases);
    Ticket ticket2("Jussara Barlabe", 7471231, company2, suitcases);

    std::cout << ticket1 << std::endl;
    std::cout << ticket2 << std::endl;


    ticket1 << 455;
    ticket1 << 73;
    ticket1 << 9;
    ticket2 << 55;
    ticket2 << 83;
    ticket2 << 32;

    //ticket1 << 455 << 73 <<  9; // <-------- Warnings here
    //ticket2 <<  55 << 83 << 32; // <-------- Warnings here

    std::cout << "\nAfter add suitcases to passenger" << std::endl;

    std::cout << ticket1 << std::endl;
    std::cout << ticket2 << std::endl;

    return 0;
}

主要问题是,当我逐个添加一个行李箱时它可以工作,但如果我尝试一次添加多个行李箱,则会出现此警告:

警告

Warning C4552   '<<': result of expression not used
Warning C4293   '<<': shift count negative or too big, undefined behavior
Warning C26452  Arithmetic overflow: Left shift count is negative or greater than or equal to the operand size which is undefined behavior (io.3).

是否有禁用默认 << 运算符的方法,或者我正在以错误的方式实现重载?! 忽略2位乘客重复行李箱ID的事实。

看看std::ostream::operator<<是如何实现的。

诀窍是使运算符实际上 return 是对第一个操作数的引用。

std::ostream& std::ostream::operator<<(...) { ... return *this; }

这样,您将获得一个可以再次调用运算符的对象,本质上是将它们链接起来。

为了能够使用

ticket1 << 455 << 73 <<  9; 

operator<< 重载必须 return 对象的引用。

而不是

bool operator << (int suitcaseID) { ... }

使用

Ticket& operator<< (int suitcaseID)
{
    for (auto suitcase : id_suitcases)
        if (suitcaseID == suitcase)
        {
            return *this;
        }
    id_suitcases.push_back(suitcaseID);
    return *this;
}

你选择 return 和 bool 的理由有些道理,但如果你不打算使用 return 值,它不会为你的程序增加任何价值。

您的 operator<< 无法链接:

bool operator << (int suitcaseID)
    {
        for (auto suitcase : id_suitcases)
            if (suitcaseID == suitcase)
            {
                return false;
            }
        id_suitcases.push_back(suitcaseID);
        return true;
    }

考虑

ticket1 << 455 << 73 <<  9;

是另一种写法

ticket1.operator<<(455).operator<<(74).operator<<(9);

链接是您 return 在 friend std::ostream& operator << (std::ostream& output, const Ticket& b) 中引用 ostream 的原因。

Return 对 Ticket 的引用以启用链接:

Ticket& operator << (int suitcaseID)
    {
        for (auto suitcase : id_suitcases)
            if (suitcaseID == suitcase)
            {
                return *this;
            }
        id_suitcases.push_back(suitcaseID);
        return *this;
    }

我认为您无论如何都没有使用 returned 值。对于应仅包含唯一元素的容器,您可以使用 std::set.