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.
which error message?
– Codigo de Senior
Invalid operands to Binary Expression ('Std::__1::ostream' (aka 'basic_ostream<char>') and 'void')
– Maria Fernanda Pedrosa
edit the question and add the error message
– Codigo de Senior