O contêiner std::vector é um dos componentes mais versáteis da Stadnard Template Library (STL) do C++. Ele funciona como um array dinâmico que pode ajustar seu tamanho automaticamente conforme novos elementos são inseridos ou removidos. Abaixo, exploramos como utilizar essa ferramenta tanto com tipos de dados primitivos quanto com objetos de classes customizadas.
1. Armazenamento de Tipos Primitivos
O uso mais comum do std::vector é o armazenamento de tipos fundamentais, como inteiros ou pontos flutuantes. Ao contrário de arrays estáticos, não precisamos definir o tamanho em tempo de compilação.
#include <iostream>
#include <vector>
int main() {
std::vector<int> valores;
// Adicionando elementos dinamicamente
valores.push_back(100);
valores.push_back(250);
valores.push_back(500);
for (size_t i = 0; i < valores.size(); ++i) {
std::cout << "Elemento na posição " << i << ": " << valores[i] << std::endl;
}
return 0;
}
2. Vetores de Objetos Customizados
O potencial do std::vector é plenamente realizado quando trabalhamos com tipos definidos pelo usuário. Imagine um sistema de recursos humanos que gerencia Candidatos e Empresas, onde existe uma lógica de compatibilidade entre eles.
Definição das Classes
Abaixo, definimos as classes Candidato e Empresa. Elas interagem entre si para verificar critérios de satisfação mútua baseados em pretensão salarial e orçamento disponível.
// Candidato.h
#pragma once
#include <string>
class Empresa;
class Candidato {
public:
Candidato(std::string nome, int idade, double pretensao);
std::string getNome() const;
double getPretensao() const;
bool aceitaProposta(const Empresa& emp) const;
std::string info() const;
private:
std::string nome;
int idade;
double pretensaoSalarial;
};
// Empresa.h
#pragma once
#include <string>
class Candidato;
class Empresa {
public:
Empresa(std::string nome, double orcamentoMaximo);
std::string getNome() const;
double getOrcamento() const;
bool validaCandidato(const Candidato& cand) const;
std::string info() const;
private:
std::string nomeEmpresa;
double orcamentoVaga;
};
Implementação da Lógica
A lógica de negócios é encapsulada nos métodos de cada classe, permitindo que o vetor gerencie as instâncias de forma limpa.
// Candidato.cpp
#include "Candidato.h"
#include "Empresa.h"
#include <sstream>
Candidato::Candidato(std::string n, int i, double p) : nome(n), idade(i), pretensaoSalarial(p) {}
std::string Candidato::getNome() const { return nome; }
double Candidato::getPretensao() const { return pretensaoSalarial; }
bool Candidato::aceitaProposta(const Empresa& emp) const {
return emp.getOrcamento() >= pretensaoSalarial;
}
std::string Candidato::info() const {
std::stringstream ss;
ss << "Candidato: " << nome << " | Pretensão: R$ " << pretensaoSalarial;
return ss.str();
}
// Empresa.cpp
#include "Empresa.h"
#include "Candidato.h"
#include <sstream>
Empresa::Empresa(std::string n, double o) : nomeEmpresa(n), orcamentoVaga(o) {}
double Empresa::getOrcamento() const { return orcamentoVaga; }
bool Empresa::validaCandidato(const Candidato& cand) const {
return cand.getPretensao() <= orcamentoVaga;
}
std::string Empresa::info() const {
std::stringstream ss;
ss << "Vaga na Empresa: " << nomeEmpresa << " | Teto Salarial: R$ " << orcamentoVaga;
return ss.str();
}
Execução com std::vector
No arquivo principal, utilizamos o contêiner para armazenar múltiplas instâncias e iterar sobre elas para exibir os dados processados.
#include <iostream>
#include <vector>
#include "Candidato.h"
#include "Empresa.h"
int main() {
// Criando instâncias de objetos
Candidato c1("Carlos Silva", 29, 7500.0);
Candidato c2("Ana Souza", 34, 9200.0);
Empresa e1("Tech Solutions", 8000.0);
Empresa e2("Global Corp", 10000.0);
// Armazenando em vetores
std::vector<Candidato> listaCandidatos;
std::vector<Empresa> listaEmpresas;
listaCandidatos.push_back(c1);
listaCandidatos.push_back(c2);
listaEmpresas.push_back(e1);
listaEmpresas.push_back(e2);
std::cout << "--- Relatório de Candidatos ---" << std::endl;
for (const auto& cand : listaCandidatos) {
std::cout << cand.info() << std::endl;
}
std::cout << "\n--- Relatório de Vagas ---" << std::endl;
for (const auto& emp : listaEmpresas) {
std::cout << emp.info() << std::endl;
}
return 0;
}
O uso de std::vector permite que o sistema escale sem a necessidade de gerenciamento manual de memória (como o uso de new e delete), reduzindo riscos de vazamentos de memória e simplificando a manutenção do código.