How to print a class in c++?

Asked

Viewed 95 times

3

Good afternoon, what am I doing wrong in printing the Team class (name, number of members) in the penultimate line of the code? Shows the error: Invalid operands to Binary Expression ('Std::__1::ostream' (aka 'basic_ostream') and 'void')

Thank you!!

#include <iostream>
#include <cstdlib>

using namespace std;

class Equipe {
public:
    string nome;
    int numeroDeMembros = 0;
    
    int getMaximoDeTorcedores();
    void imprimir();
};
    int Equipe::getMaximoDeTorcedores(){
        int max = 15+25*numeroDeMembros;
        return max;
    }
    void Equipe::imprimir(){
        cout<<nome<<endl;
        cout<<numeroDeMembros<<endl;
    }
int main(int argc, char** argv){
    
    Equipe *e1 = new Equipe;
    Equipe *e2 = new Equipe;
    
    e1->nome = "Fulano";
    e2->nome = "Beltrano";
    e1->numeroDeMembros = 22;
    e2->numeroDeMembros = 12;
   
    cout<< e1->getMaximoDeTorcedores() <<endl;
    cout<< e2->getMaximoDeTorcedores() <<endl;
    cout<< e1->imprimir()<<endl;
    
    
 
    return 0;
}
  • 1

    which error message?

  • Invalid operands to Binary Expression ('Std::__1::ostream' (aka 'basic_ostream<char>') and 'void')

  • edit the question and add the error message

2 answers

3

How to print a class in c++

is something very generic.

I’ll show you a common example, and also show why what you tried to write doesn’t work, although it’s already clear in the @Maniero reply

Its implementation of imprimir()

void Equipe::imprimir() {
    cout << nome << endl;
    cout << numeroDeMembros << endl;
}

imprimir() returns void and you wrote

cout << imprimir();

  • what is cout? cout is an output stream, declared ostream
  • what is <<? It is the insertion operator and has many versions for the case of cout who’s kind ostream. Behold:
arithmetic types (1)    
ostream& operator<< (bool val);
ostream& operator<< (short val);
ostream& operator<< (unsigned short val);
ostream& operator<< (int val);
ostream& operator<< (unsigned int val);
ostream& operator<< (long val);
ostream& operator<< (unsigned long val);
ostream& operator<< (long long val);
ostream& operator<< (unsigned long long val);
ostream& operator<< (float val);
ostream& operator<< (double val);
ostream& operator<< (long double val);
ostream& operator<< (void* val);
stream buffers (2)  
ostream& operator<< (streambuf* sb );
manipulators (3)    
ostream& operator<< (ostream& (*pf)(ostream&));
ostream& operator<< (ios& (*pf)(ios&));
ostream& operator<< (ios_base& (*pf)(ios_base&));

how are you in Cplusplus.com

Note that you have no option for void which is what its function imprimir() returns. and so the compiler complained. And note that you have an option for everything that is common type and so you can write cout << "teste" or cout << inteiro or anyone on the list: because you’re on the list.

The most common thing to print a class is to do the same thing as in the list above: create a version of << for your class Equipe and so the compiler is satisfied and you have more flexibility to control the output, being able to write only cout << e1; for e1 an instance of Equipe, of course. It’s called Overload and it’s just a reset of the operator. You can reset almost all of them in C++. The most common think is even <<. And () It’s a big case, as you’ll see in the future. Instead of having for example a function soma() to add two Equipe you do this: reset the operator + and put the code there. Instead of having imprimir() you redefine <<. It is a very useful concept and makes the code look very compact and readable, but in the background are only functions and a syntactic glue.

I’ll show you an example with your code, but you can see something nicer documented in Microsoft Docs

a very simple example with your code

using Overload of <<

What did I change? You’ll see that I created a Member class and put on the team a fixed vector of 10 of them. It’s just an example after all. This for the new version of imprimir() show something like that

Equipe 'Fulano' [4] membros  Max 115 torcedores
   1    2                nome
   2    2                dois
   3    2               outro
   4    2                esse

Equipe 'Beltrano' [0] membros  Max 15 torcedores

For a code like this

int main(void)
{
    Equipe e1("Fulano");
    Equipe e2("Beltrano");

    e1.insereNaEquipe(Membro(1, 2, "nome"));
    e1.insereNaEquipe(Membro(2, 2, "dois"));
    e1.insereNaEquipe(Membro(3, 2, "outro"));
    e1.insereNaEquipe(Membro(4, 2, "esse"));

    cout << e1;
    cout << e2;

    return 0;
}

Notice I put two builders there to Equipe. Understand that in general it is not written as you did, initialize values in the class definition. This only gives problem. Classes have constructors that exist for this, and if you put a value there you can put a different one in the constructor and then not notice the problem. And now you can name Equipe right in the statement. You can have a number of any constructors and with different parameters. That’s such polymorphism.

Here’s your slightly altered code

#include <iomanip>
#include <iostream>
//#include <cstdlib>

using namespace std;

struct Membro
{
    int id;
    int idade;
    string nome;

    Membro() : id(0), idade(0), nome("") {};
    Membro(int n, int idade, string nome) :
        id(n), idade(idade), nome(nome) {};
};

class Equipe
{
public:
    string nome;
    int numeroDeMembros;
private:
    Membro      membro[10];

public:
    Equipe() : numeroDeMembros(0) {};
    Equipe(string n) : numeroDeMembros(0), nome(n){};

    int getMaximoDeTorcedores() const;
    int     insereNaEquipe(Membro);

    friend  ostream& operator<<(ostream&, const Equipe&);

};  // Equipe{}

int main(void)
{
    Equipe e1("Fulano");
    Equipe e2("Beltrano");

    e1.insereNaEquipe(Membro(1, 2, "nome"));
    e1.insereNaEquipe(Membro(2, 2, "dois"));
    e1.insereNaEquipe(Membro(3, 2, "outro"));
    e1.insereNaEquipe(Membro(4, 2, "esse"));

    cout << e1;
    cout << e2;

    return 0;
}

int Equipe::getMaximoDeTorcedores() const
{
    int max = 15 + 25 * numeroDeMembros;
    return max;
}

int Equipe::insereNaEquipe(Membro um)
{
    if (numeroDeMembros >= 10) return -1;
    membro[numeroDeMembros].nome = um.nome;
    membro[numeroDeMembros].id = um.id;
    membro[numeroDeMembros].idade = um.idade;
    numeroDeMembros += 1;
    return numeroDeMembros;
};

ostream& operator<<(ostream& saida, const Equipe& E)
{
    saida << "Equipe '" << E.nome <<
        "' [" << E.numeroDeMembros << "] membros " <<
        " Max " << E.getMaximoDeTorcedores() <<
        " torcedores\n";
    for (int m =0; m<E.numeroDeMembros; m+=1)
        saida <<
        setw(4) <<  E.membro[m].id <<
        setw(5) <<  E.membro[m].idade <<
        setw(20) << E.membro[m].nome << endl;
    saida << endl;
    return saida;
};

See if you understand the difference and ask about what you find strange

on the printing() of new clothing

    friend  ostream& operator<<(ostream&, const Equipe&);

This is the usual statement. This specifier is usually used friend then because without it the function will not have access to variables or class methods marked as private. This is the effect and you can declare any function like this.

What’s the difference that she’s just part of the class? It is: if it is part of the class it can only be used together with an instance of the class, and in many cases it is not practical and so comes this sweet notion of friendship between classes and methods.

2

The printing method already makes the impression, it is not a stream of data or even it even returns some data, you should call it directly and not in a cout waiting for a stream. The impression occurs within it.

#include <iostream>
using namespace std;

class Equipe {
public:
    string nome;
    int numeroDeMembros = 0;
    int getMaximoDeTorcedores();
    void imprimir();
};
int Equipe::getMaximoDeTorcedores() {
    return 15 + 25 * numeroDeMembros;
}
void Equipe::imprimir() {
    cout << nome << endl;
    cout << numeroDeMembros << endl;
}
int main(){
    Equipe *e1 = new Equipe;
    Equipe *e2 = new Equipe;
    e1->nome = "Fulano";
    e2->nome = "Beltrano";
    e1->numeroDeMembros = 22;
    e2->numeroDeMembros = 12;
    cout << e1->getMaximoDeTorcedores() << endl;
    cout << e2->getMaximoDeTorcedores() << endl;
    e1->imprimir();
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.