# 12 - Structs
Uma struct é um tipo que pode conter zero ou mais variáveis que são alocadas de uma forma ordenada.
O tamanho de uma struct depende do tamanho dos elementos que ela contem.
Normalmente o tamanho será o tamanho do maior elemento em bytes * o número de elementos.
Usamos structs para agrupar valores ou para representar uma entidade.
O tipo dos elementos que uma struct contem não precisam ser o mesmo.
struct NOME_DA_STRUCT { };
#include <iostream>
#include <string>
struct Pessoa {
std::string nome;
int idade;
};
int main()
{
/* Variáveis são declaradas da mesma forma que com tipos primitivos */
Pessoa pessoa;
/* Usamos . para acessar coisas que estão dentro de uma struct */
pessoa.nome = "John doe";
pessoa.idade = 30;
std::cout << "A idade de " << pessoa.nome << " e " << pessoa.idade;
}
Structs podem conter funções, além de variáveis.
#include <iostream>
#include <string>
struct Pessoa {
std::string nome;
int idade;
void apresentar() {
std::cout << "Meu nome e " << nome << " e tenho " << idade << " anos";
}
};
int main()
{
Pessoa pessoa;
pessoa.nome = "John doe";
pessoa.idade = 30;
pessoa.apresentar();
}
Structs possuem uma função especial que é chamada quando uma instância daquela struct é criada. Essa função é chamada de construtor, normalmente usada para dar valores para as variáveis que uma struct possui.
O construtor é uma função normal, exceto pelo fato de que não tem um tipo de retorno e só deve ser chamada uma vez de maneira automática.
Quando acessamos uma variável de uma struct, dentro dela mesmo, podemos usar this
para deixar explicito que a quem tal variável pertence. Isso não é necessário na maioria dos casos, a não ser por preferência ou por um caso onde existe ambiguidade.
#include <iostream>
#include <string>
struct Pessoa {
std::string nome;
int idade;
/* O construtor não precisa de um tipo de retorno
*
* Usando this para deixar explicito que estamos copiando o valor das variáveis nome e idade
* passadas nos construtor, para as variáveis nome e idade da instância da struct.
**/
Pessoa(std::string nome, int idade) {
this->nome = nome;
this->idade = idade;
}
void apresentar() {
std::cout << "Meu nome e " << nome << " e tenho " << idade << " anos";
}
};
int main()
{
Pessoa pessoa("John Doe", 30);
pessoa.apresentar();
}
Caso nenhum construtor seja declarado, o compilador irá criar um construtor vazio.
Por exemplo:
#include <iostream>
#include <string>
struct Pessoa {
std::string nome;
int idade;
/* Criado pelo compilador */
Pessoa() {}
void apresentar() {
std::cout << "Meu nome e " << nome << " e tenho " << idade << " anos";
}
};
int main()
{
Pessoa pessoa;
}
Podemos ter mais de um construtor, com cada um deles fazendo uma coisa diferente.
#include <iostream>
#include <string>
struct Pessoa {
std::string nome;
int idade;
/* Primeiro */
Pessoa(std::string nome, int idade) {
this->nome = nome;
this->idade = idade;
}
/* Segundo */
Pessoa(std::string nome) {
this->nome = nome;
this->idade = -1 // Vamos considerar -1 como desconhecido
}
/* Terceiro */
Pessoa(int idade) {
this->nome = "desconhecido";
this->idade = idade;
}
void apresentar() {
std::cout << "Meu nome e " << nome << " e tenho " << idade << " anos";
}
};
int main()
{
Pessoa pessoa("John Doe", 30); // Chama o primeiro construtor
Pessoa pessoa("John Doe"); // Chama o segundo construtor
Pessoa pessoa(30); // Chama o terceiro construtor
}