C++: Noções Básicas de Classes e Objetos
Última atualização: 2026-08-26
Nas aulas anteriores, usamos structs para combinar variáveis de tipos diferentes em uma única unidade.
Mas coisas do mundo real têm não apenas atributos (como nome, idade) mas também comportamentos (como andar, falar).
Classes são usadas para descrever "coisas" — elas encapsulam atributos e comportamentos juntos.
1. O que é uma Classe?
(1) 1.1 Classes no Dia a Dia
| Exemplo do Dia a Dia | Equivalente no Programa |
|---|---|
| Uma planta arquitetônica (descreve a estrutura de uma casa) | Classe (um molde que descreve coisas) |
| Uma casa construída a partir da planta (o objeto real) | Objeto (uma instância de uma classe) |
Classe vs Objeto:
- Uma classe é um molde (descreve que atributos e comportamentos um "estudante" deve ter)
- Um objeto é uma instância (uma coisa concreta criada a partir do molde — o estudante "Zhang San")
(2) 1.2 Por que Precisamos de Classes?
Sem classes (usando structs, com limitações):
#include <iostream>
#include <string>
struct Student {
std::string name;
int age;
double score;
};
int main() {
Student s1 = {"Alice", 20, 92.5};
// ❌ Structs não podem incluir "comportamentos" (como "apresente-se")
return 0;
}
Com classes (completo):
#include <iostream>
#include <string>
class Student {
public:
std::string name;
int age;
double score;
void introduce() {
std::cout << "Meu nome é " << name << ",tenho " << age << " anos。" << std::endl;
}
};
int main() {
Student s1;
s1.name = "Alice";
s1.age = 20;
s1.introduce(); // ✅ Classes podem incluir "comportamentos"
return 0;
}
2. Definição de Classe*
(1) 2.1 Sintaxe Básica
class ClassName {
public:
// membros (atributos e comportamentos)
};
💡 Ponto Importante: Uma definição de classe termina com um ponto e vírgula! (O mesmo que structs)
▶ Exemplo 1: Definindo uma Classe Student (Dificuldade ⭐)
#include <iostream>
#include <string>
class Student {
public:
// atributos (variáveis membro)
std::string name;
int age;
double score;
// comportamentos (funções membro)
void introduce() {
std::cout << "Meu nome é " << name << ",tenho " << age << " anos。" << std::endl;
}
void study() {
std::cout << name << " está estudando..." << std::endl;
}
};
int main() {
Student s1;
s1.name = "Alice";
s1.age = 20;
s1.score = 92.5;
s1.introduce();
s1.study();
return 0;
}
Saída:
Meu nome é Alice,tenho 20 anos。
Alice está estudando...
3. Controle de Acesso*
Classes em C++ têm três níveis de acesso: public, private e protected.
(1) 3.1 public vs private*
| Nível de Acesso | Acessível Fora da Classe? | Propósito |
|---|---|---|
| public | ✅ Sim | Interface pública (para uso externo) |
| private | ❌ Não | Implementação interna (ocultar detalhes) |
Exemplo:
#include <iostream>
#include <string>
class Student {
private:
std::string name; // membro privado
int age;
public:
// setter e getter públicos
void setName(const std::string& n) {
name = n;
}
std::string getName() {
return name;
}
};
int main() {
Student s1;
// s1.name = "Alice"; // ERRO: name é privado
s1.setName("Alice"); // OK: acesso via função pública
std::cout << s1.getName() << std::endl;
return 0;
}
💡 Princípio de Encapsulamento: Torne os atributos private, e acesse-os através de métodos setter/getter public — isso permite controlar a lógica de acesso (ex.: verificar se a idade é negativa).
4. Construtores*
(1) 4.1 O que é um Construtor?
Um construtor é uma função especial em uma classe — ele é chamado automaticamente quando um objeto é criado.
| Característica | Descrição |
|---|---|
| Nome | Mesmo nome da classe |
| Sem retorno | Nem mesmo void |
| Chamada automática | Executa quando um objeto é criado |
▶ Exemplo 2: Definindo um Construtor (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
class Student {
private:
std::string name;
int age;
public:
// construtor
Student(const std::string& n, int a) {
name = n;
age = a;
std::cout << "Objeto Student criado: " << name << std::endl;
}
void introduce() {
std::cout << "Meu nome é " << name << ",tenho " << age << " anos。" << std::endl;
}
};
int main() {
Student s1("Alice", 20); // OK: construtor chamado automaticamente ao criar o objeto
s1.introduce();
return 0;
}
Saída:
Objeto Student criado: Alice
Meu nome é Alice,tenho 20 anos。
5. Destrutores*
(1) 5.1 O que é um Destrutor?
Um destrutor é outra função especial em uma classe — ele é chamado automaticamente quando um objeto é destruído (ex.: quando uma função termina, ou quando delete é chamado).
| Característica | Descrição |
|---|---|
| Nome | ~ClassName |
| Sem retorno | Nem mesmo void |
| Sem parâmetros | Não pode aceitar parâmetros |
| Chamada automática | Executa quando um objeto é destruído |
▶ Exemplo 3: Definindo um Destrutor (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
class Student {
private:
std::string name;
public:
// construtor
Student(const std::string& n) {
name = n;
std::cout << "Construtor: " << name << " criado" << std::endl;
}
// destrutor
~Student() {
std::cout << "Destrutor: " << name << " destruído" << std::endl;
}
};
int main() {
Student s1("Alice"); // chama construtor
// quando main() termina, s1 é destruído, destrutor é chamado
return 0;
}
Saída:
Construtor: Alice criado
Destrutor: Alice destruído
💡 Uso: Liberar recursos no destrutor (ex.: fechar arquivos, liberar memória dinâmica).
6. O Ponteiro this*
(1) 6.1 O que é o Ponteiro this?
this é um ponteiro para o objeto atual — dentro de uma função membro, this pode ser usado para acessar o objeto atual.
▶ Exemplo 4: Usando this para Distinguir Parâmetros com o Mesmo Nome (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
class Student {
private:
std::string name;
public:
void setName(const std::string& name) { // AVISO: nome do parâmetro igual ao da variável membro
this->name = name; // OK: usar this-> para acessar a variável membro
}
std::string getName() {
return this->name; // OK: this-> pode ser omitido (recomendado omitir)
}
};
int main() {
Student s1;
s1.setName("Alice");
std::cout << s1.getName() << std::endl;
return 0;
}
Saída:
Alice
💡 Dica: Se o nome do parâmetro for diferente do nome da variável membro, você não precisa de this-> (é recomendado omiti-lo para um código mais limpo).
7. Prática: Classe Simples de Conta Bancária*
▶ Exemplo 5: Classe BankAccount (Dificuldade ⭐⭐⭐)
#include <iostream>
#include <string>
#include <iomanip>
class BankAccount {
private:
std::string owner;
double balance;
public:
// construtor
BankAccount(const std::string& o, double initialBalance) {
owner = o;
if (initialBalance >= 0) {
balance = initialBalance;
} else {
balance = 0.0;
std::cout << "⚠️ Saldo inicial não pode ser negativo, definido como 0" << std::endl;
}
}
// depósito
void deposit(double amount) {
if (amount > 0) {
balance += amount;
std::cout << "Depósito realizado! +" << amount << std::endl;
} else {
std::cout << "⚠️ Valor do depósito deve ser maior que 0" << std::endl;
}
}
// saque
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
std::cout << "Saque realizado! -" << amount << std::endl;
} else if (amount <= 0) {
std::cout << "⚠️ Valor do saque deve ser maior que 0" << std::endl;
} else {
std::cout << "⚠️ Saldo insuficiente" << std::endl;
}
}
// consultar saldo
void queryBalance() {
std::cout << std::fixed << std::setprecision(2);
std::cout << "Saldo da conta: " << balance << " yuan" << std::endl;
}
};
int main() {
BankAccount account("MOTO", 1000.0);
account.queryBalance();
account.deposit(500.0);
account.queryBalance();
account.withdraw(200.0);
account.queryBalance();
account.withdraw(2000.0); // saldo insuficiente
return 0;
}
Saída:
Saldo da conta: 1000.00 yuan
Depósito realizado! +500.00
Saldo da conta: 1500.00 yuan
Saque realizado! -200.00
Saldo da conta: 1300.00 yuan
⚠️ Saldo insuficiente
Resultado da Execução:
Saldo da conta: 1000.00 yuan
Depósito realizado! +500.00
Saldo da conta: 1500.00 yuan
Saque realizado! -200.00
Saldo da conta: 1300.00 yuan
⚠️ Saldo insuficiente
❓ Perguntas Frequentes
P: Qual a diferença entre class e struct? R: Apenas uma coisa — o nível de acesso padrão é diferente: > -
classtem padrãoprivate> -structtem padrãopublicTodo o resto é exatamente igual! Então
structtambém pode ter funções membro e construtores.Recomendação: Use
classquando quiser encapsulamento (ocultar detalhes); usestructpara coleções simples de dados.
P: Construtores podem ser sobrecarregados? R: Sim! Você pode definir múltiplos construtores (com parâmetros diferentes).
CPPclass Student { public: Student() { ... } // construtor sem argumentos Student(const std::string& n) { ... } // construtor parametrizado };
P: O que acontece se eu não escrever um construtor? R: O compilador gera automaticamente um construtor padrão (sem parâmetros, que não faz nada).
Mas se você escrever qualquer construtor, o compilador não gerará mais automaticamente um construtor padrão.
CPPclass Student { public: Student(const std::string& n) { ... } // escreveu um construtor parametrizado int main() { Student s1; // ERRO: não há mais construtor sem argumentos return 0; }
📖 Resumo
- Classes: encapsulam dados e operações juntos
- Objetos são instâncias de classes, acessados via . ou ->
- Modificadores de acesso: public/protected/private
- Funções membro são declaradas dentro da classe e podem ser definidas dentro ou fora
- Construtores: chamados automaticamente quando um objeto é criado, usados para inicialização
📝 Exercícios
-
Básico (Dificuldade ⭐): Defina uma classe
Bookcom três membros privados: título, autor e preço. -
Forneça métodos públicos setter e getter
-
Crie dois objetos
Bookemmaine exiba suas informações -
Intermediário (Dificuldade ⭐⭐): Defina uma classe
Rectanglecom dois membros privados: largura e altura. -
Forneça um construtor parametrizado
-
Forneça funções membro
double getArea()edouble getPerimeter() -
Teste em
main -
Desafio (Dificuldade ⭐⭐⭐): Defina uma classe
Datecom três membros privados: ano, mês e dia. -
Forneça um construtor parametrizado
-
Forneça uma função membro
bool isValid()(verifica se a data é válida) -
Forneça uma função membro
void print()(exibe a data no formato:2024-02-29) -
Teste em
main
8. 🚀 Próximos Passos*
Agora que você aprendeu o básico de classes e objetos, vamos avançar para Construtores Avançados (Aula 29) — construtores padrão, construtores de cópia e semântica de movimentação (um recurso do C++11)!