Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
135 views
in Technique[技术] by (71.8m points)

c++ - Overload operator '<<' without output streaming intentions

I'm new to operators overlading and i'm facing this chalange: I have this class Ticket and i'm creating 2 objects Ticket, ticket1 and ticket2. Each ticket have an ammount of suitcases, i store that ids into a vector named id_suitcases.

Now i want to be able to add severals suitcaseID's to that vector using operator <<

eg.

Output:

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

Using Operator << like this

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

Output:

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 Ticket

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;
    }
};

Main

int main()
{
    std::cout << "19/20 NORMAL
";
    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 << "
After add suitcases to passenger" << std::endl;

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

    return 0;
}

The main problem is, when i add suitcase by suitcase it works, but if i try to add several suitcases at once this warnings appear:

Warnings

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).

It's there a way to disable default << operator or i'm implementing the overload in a bad way?! Ignore the fact that 2 passengers have repeted suitcasesID's.

question from:https://stackoverflow.com/questions/65905581/overload-operator-without-output-streaming-intentions

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your operator<< cannot chain:

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

Consider that

ticket1 << 455 << 73 <<  9;

is a different way of writing

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

Chaining is the reason you return the reference to the ostream in your friend std::ostream& operator << (std::ostream& output, const Ticket& b).

Return a refeference to the Ticket to enable chaining:

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

I think you didnt use the returned value anyhow. For a container that should contain only unique elements you can use a std::set.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...