Pular para conteúdo

Funções e Classes

Funções definem contratos; classes combinam representação, invariantes e operações. Boas interfaces tornam posse e falha visíveis.

Passagem de parâmetros

Forma Significado típico
T value Copiar/mover valor pequeno ou receber sua posse
T const& value Ler sem copiar; não pode sobreviver ao objeto
T& value Alterar objeto do chamador
T* value Acesso opcional ou reposicionável sem posse
std::unique_ptr<T> Transferir posse exclusiva
std::shared_ptr<T> Compartilhar posse como parte do contrato

Não use shared_ptr apenas para evitar decidir a posse. Passe smart pointer quando sua semântica for relevante ao receptor.

Um invariante de classe

class percentage {
public:
    explicit percentage(double value) : value_{value} {
        if (!(value >= 0.0 && value <= 100.0)) {
            throw std::out_of_range{"percentage outside [0, 100]"};
        }
    }

    [[nodiscard]] double value() const noexcept { return value_; }

private:
    double value_;
};

O construtor estabelece o invariante. explicit impede conversão involuntária. [[nodiscard]] solicita diagnóstico para resultado ignorado; noexcept integra o tipo e o contrato de falha/otimização.

Construção e destruição

Membros são inicializados na ordem de declaração, não da lista. Subobjetos base vêm antes dos membros; destruição ocorre em ordem inversa. Não chame funções virtuais no construtor/destrutor esperando despacho para parte mais derivada.

Regra do Zero

Prefira membros que gerenciem seus recursos para que destrutor, cópias, movimentações e atribuições gerados tenham semântica correta. Se a classe gerencia recurso manualmente, a Regra dos Cinco aponta as operações especiais a revisar.

Overload e argumentos padrão

Overload é resolvido em compilação. Argumentos padrão são substituídos conforme a declaração visível no ponto da chamada, não por despacho dinâmico. Evite conjuntos ambíguos.

Headers e definições

Headers normalmente contêm declarações, classes, templates e definições inline. Fontes contêm definições não inline. Use guards ou #pragma once, minimize includes e não coloque using namespace amplo em headers.

Exercícios

  1. Projete classe cujo construtor imponha nome não vazio.
  2. Explique a ordem de inicialização dos membros.
  3. Decida como receber objeto grande somente para leitura e sem retê-lo.