# 3. Funcoes & Classes & Estruturas

## Introdução

C e C++ são linguagens que suportam programação estruturada e, no caso do C++, também programação orientada a objetos. Funções são blocos de código reutilizáveis, enquanto **structs** (em C) e **classes** (em C++) permitem agrupar dados e comportamentos. Diferente do PHP, C/C++ possui **tipagem estática** e requer gerenciamento manual de memória, o que torna essencial compreender passagem de parâmetros, ponteiros e ciclos de vida de objetos.

## Funções em C e C++

### Definição e Declaração

```c
// Declaração (protótipo) - opcional, mas recomendada
int soma(int a, int b);

// Definição
int soma(int a, int b) {
    return a + b;
}

// Uso
int resultado = soma(5, 3);
```

**Comportamento do Computador:**

* O compilador reserva espaço na **stack** para parâmetros e variáveis locais.
* Parâmetros são **copiados** por padrão (passagem por valor).
* O valor de retorno é armazenado em registradores ou na stack.
* Funções sem retorno usam `void`.

### Tipos de Retorno

```c
// Sem retorno
void log_mensagem(const char* msg) {
    printf("[LOG] %s\n", msg);
}

// Retorno inteiro
int obter_status() {
    return 200;
}

// Retorno ponteiro (cuidado com escopo!)
int* criar_array(int tamanho) {
    int* arr = (int*)malloc(tamanho * sizeof(int));
    return arr;  // OK: memória alocada na heap
}
```

### Parâmetros: Passagem por Valor vs Referência

#### Passagem por Valor (C e C++)

```c
void incrementar(int x) {
    x++;  // Apenas a cópia é modificada
}

int a = 10;
incrementar(a);
printf("%d\n", a);  // 10 (inalterado)
```

#### Passagem por Referência com Ponteiros (C e C++)

```c
void incrementar(int *x) {
    (*x)++;  // Modifica o original
}

int a = 10;
incrementar(&a);
printf("%d\n", a);  // 11 (modificado)
```

#### Passagem por Referência (C++ apenas)

```cpp
void incrementar(int &x) {
    x++;  // Modifica o original (sintaxe mais simples)
}

int a = 10;
incrementar(a);
cout << a << endl;  // 11
```

### Parâmetros Padrão (C++ apenas)

```cpp
void saudacao(const string& nome = "Visitante") {
    cout << "Olá, " << nome << "!" << endl;
}

saudacao("Alice");   // Olá, Alice!
saudacao();          // Olá, Visitante!
```

### Sobrecarga de Funções (C++ apenas)

```cpp
int soma(int a, int b) {
    return a + b;
}

double soma(double a, double b) {
    return a + b;
}

int soma(int a, int b, int c) {
    return a + b + c;
}
```

**Comportamento do Computador:**

* O compilador **mangle** (decora) os nomes das funções com informações de tipo (name mangling).
* A sobrecarga é resolvida em tempo de compilação baseada nos argumentos.

### Funções Inline (C e C++)

Sugere ao compilador substituir a chamada pelo corpo da função.

```c
inline int quadrado(int x) {
    return x * x;
}
```

**Comportamento do Computador:**

* Evita overhead de chamada de função.
* Compilador pode ignorar a sugestão para funções complexas.

### Funções Variádicas (Número Variável de Argumentos)

```c
#include <stdarg.h>

int soma_variada(int count, ...) {
    va_list args;
    va_start(args, count);
    
    int total = 0;
    for (int i = 0; i < count; i++) {
        total += va_arg(args, int);
    }
    
    va_end(args);
    return total;
}

int resultado = soma_variada(3, 10, 20, 30);  // 60
```

## Structs em C

Structs agrupam dados de diferentes tipos em uma única unidade.

### Declaração e Uso

```c
struct Pessoa {
    char nome[50];
    int idade;
    float altura;
};

// Declaração de variável
struct Pessoa p1;

// Inicialização
struct Pessoa p2 = {"Alice", 25, 1.65};

// Acesso
p1.idade = 30;
strcpy(p1.nome, "Bob");
printf("Nome: %s, Idade: %d\n", p1.nome, p1.idade);
```

### Typedef (Alias para Struct)

```c
typedef struct {
    char nome[50];
    int idade;
    float altura;
} Pessoa;

Pessoa p1 = {"Alice", 25, 1.65};  // Sem necessidade de 'struct'
```

### Ponteiros para Struct

```c
Pessoa *ptr = &p1;
ptr->idade = 26;           // Equivalente a (*ptr).idade
printf("%d\n", ptr->idade);
```

### Structs Aninhadas

```c
struct Endereco {
    char rua[100];
    int numero;
    char cidade[50];
};

struct Pessoa {
    char nome[50];
    int idade;
    struct Endereco endereco;
};

Pessoa p = {"Alice", 25, {"Rua A", 123, "São Paulo"}};
printf("%s\n", p.endereco.cidade);
```

### Tamanho e Alinhamento

```c
struct Exemplo {
    char c;     // 1 byte
    int i;      // 4 bytes (com padding de 3 bytes após c)
    short s;    // 2 bytes (com padding de 2 bytes após i)
};
// Tamanho total: geralmente 12 bytes (depende do compilador)
```

## Classes em C++

Classes são a base da Programação Orientada a Objetos em C++, encapsulando dados e métodos.

### Declaração Básica

```cpp
class Pessoa {
private:
    std::string nome;
    int idade;
    
public:
    // Construtor
    Pessoa(const std::string& n, int i) : nome(n), idade(i) {}
    
    // Métodos
    void apresentar() const {
        std::cout << "Olá, sou " << nome << " e tenho " << idade << " anos." << std::endl;
    }
    
    // Getters
    std::string getNome() const { return nome; }
    int getIdade() const { return idade; }
    
    // Setters
    void setIdade(int i) { idade = i; }
};

// Uso
Pessoa p1("Alice", 25);
p1.apresentar();
p1.setIdade(26);
```

### Modificadores de Acesso

| Modificador | Acesso                                     |
| ----------- | ------------------------------------------ |
| `public`    | Acessível de qualquer lugar                |
| `private`   | Acessível apenas dentro da classe (padrão) |
| `protected` | Acessível na classe e em classes derivadas |

### Construtores e Destrutores

```cpp
class Arquivo {
private:
    FILE* fp;
    
public:
    // Construtor
    Arquivo(const char* nome) {
        fp = fopen(nome, "r");
        if (fp == NULL) {
            throw std::runtime_error("Não foi possível abrir arquivo");
        }
    }
    
    // Destrutor (chamado automaticamente quando objeto é destruído)
    ~Arquivo() {
        if (fp != NULL) {
            fclose(fp);
        }
    }
    
    // Método
    void ler() { /* ... */ }
};
```

### Construtores de Cópia e Operador de Atribuição

```cpp
class Vetor {
private:
    int* dados;
    size_t tamanho;
    
public:
    // Construtor
    Vetor(size_t n) : tamanho(n) {
        dados = new int[n];
    }
    
    // Destrutor
    ~Vetor() {
        delete[] dados;
    }
    
    // Construtor de cópia (deep copy)
    Vetor(const Vetor& outro) : tamanho(outro.tamanho) {
        dados = new int[tamanho];
        for (size_t i = 0; i < tamanho; i++) {
            dados[i] = outro.dados[i];
        }
    }
    
    // Operador de atribuição
    Vetor& operator=(const Vetor& outro) {
        if (this != &outro) {
            delete[] dados;
            tamanho = outro.tamanho;
            dados = new int[tamanho];
            for (size_t i = 0; i < tamanho; i++) {
                dados[i] = outro.dados[i];
            }
        }
        return *this;
    }
};
```

### Herança

```cpp
class Animal {
protected:
    std::string nome;
    
public:
    Animal(const std::string& n) : nome(n) {}
    
    virtual void emitirSom() const {
        std::cout << nome << " faz um som" << std::endl;
    }
    
    virtual ~Animal() {}  // Destrutor virtual para polimorfismo
};

class Cachorro : public Animal {
public:
    Cachorro(const std::string& n) : Animal(n) {}
    
    void emitirSom() const override {
        std::cout << nome << " late: Au au!" << std::endl;
    }
};

class Gato : public Animal {
public:
    Gato(const std::string& n) : Animal(n) {}
    
    void emitirSom() const override {
        std::cout << nome << " mia: Miau!" << std::endl;
    }
};

// Polimorfismo
Animal* a1 = new Cachorro("Rex");
Animal* a2 = new Gato("Mimi");
a1->emitirSom();  // Rex late: Au au!
a2->emitirSom();  // Mimi mia: Miau!
delete a1;
delete a2;
```

### Métodos Virtuais e Tabelas Virtuais (vtable)

**Comportamento do Computador:**

* Classes com métodos virtuais possuem uma **vtable** (tabela virtual) gerada pelo compilador.
* Cada objeto contém um ponteiro oculto (`vptr`) para a vtable da classe.
* Chamadas virtuais são resolvidas em tempo de execução através da vtable.
* Overhead de memória (um ponteiro por objeto) e performance (indireção).

### Classes Abstratas (Interfaces)

```cpp
class Forma {
public:
    virtual double area() const = 0;  // Método virtual puro
    virtual ~Forma() {}
};

class Circulo : public Forma {
private:
    double raio;
    
public:
    Circulo(double r) : raio(r) {}
    
    double area() const override {
        return 3.14159 * raio * raio;
    }
};
```

### Templates (C++)

Templates permitem código genérico.

```cpp
// Template de função
template <typename T>
T maximo(T a, T b) {
    return (a > b) ? a : b;
}

int a = maximo(10, 20);      // T = int
double b = maximo(3.14, 2.71); // T = double

// Template de classe
template <typename T>
class Pilha {
private:
    std::vector<T> dados;
    
public:
    void push(const T& valor) {
        dados.push_back(valor);
    }
    
    T pop() {
        T valor = dados.back();
        dados.pop_back();
        return valor;
    }
    
    bool vazia() const {
        return dados.empty();
    }
};

Pilha<int> pilhaInt;
pilhaInt.push(10);
pilhaInt.push(20);
```

## Estruturas de Dados Avançadas

### Union (C e C++)

Uma union compartilha o mesmo espaço de memória entre diferentes tipos.

```c
union Dado {
    int i;
    float f;
    char str[20];
};

union Dado valor;
valor.i = 42;
printf("%d\n", valor.i);   // 42
valor.f = 3.14;
printf("%f\n", valor.f);   // 3.14 (sobrescreve i)
```

**Comportamento do Computador:**

* Union ocupa espaço equivalente ao seu maior membro.
* Apenas um membro pode ser usado por vez.
* Útil para economizar memória ou interpretar dados de diferentes formas.

### Enum (C e C++)

Define um conjunto de constantes nomeadas.

```c
enum Status {
    STATUS_SUCESSO = 200,
    STATUS_ERRO = 500,
    STATUS_NAO_ENCONTRADO = 404
};

enum Status status = STATUS_SUCESSO;
```

### Enum Class (C++11) - Mais Seguro

```cpp
enum class Status {
    Sucesso = 200,
    Erro = 500,
    NaoEncontrado = 404
};

Status s = Status::Sucesso;
// Não há conversão implícita para inteiro
if (s == Status::Sucesso) {
    // OK
}
```

## Funções Membro Estáticas (C++)

Pertencem à classe, não às instâncias.

```cpp
class Contador {
private:
    static int totalInstancias;
    
public:
    Contador() {
        totalInstancias++;
    }
    
    ~Contador() {
        totalInstancias--;
    }
    
    static int getTotal() {
        return totalInstancias;
    }
};

int Contador::totalInstancias = 0;  // Inicialização

Contador c1, c2;
std::cout << Contador::getTotal() << std::endl;  // 2
```

## Funções Amigas (C++)

Permitem que funções ou classes externas acessem membros privados.

```cpp
class Matriz {
private:
    int dados[3][3];
    
public:
    friend Matriz transposta(const Matriz& m);
};

Matriz transposta(const Matriz& m) {
    Matriz resultado;
    // Acessa dados privados de m
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            resultado.dados[i][j] = m.dados[j][i];
        }
    }
    return resultado;
}
```

## Boas Práticas

{% stepper %}
{% step %}

#### Use `const` em parâmetros e métodos

```cpp
// Parâmetro constante
void imprimir(const std::string& texto) {
    std::cout << texto << std::endl;
}

// Método constante (não modifica o objeto)
int getValor() const {
    return valor;
}
```

{% endstep %}

{% step %}

#### Evite variáveis globais

Prefira passagem de parâmetros ou encapsulamento em classes.
{% endstep %}

{% step %}

#### Use RAII (Resource Acquisition Is Initialization)

Recursos (memória, arquivos, locks) devem ser adquiridos no construtor e liberados no destrutor.
{% endstep %}

{% step %}

#### Prefira inicialização por lista de inicialização

```cpp
class Exemplo {
private:
    int a;
    int b;
    
public:
    // Bom: inicialização direta
    Exemplo(int x, int y) : a(x), b(y) {}
    
    // Ruim: atribuição no corpo
    Exemplo(int x, int y) {
        a = x;
        b = y;
    }
};
```

{% endstep %}

{% step %}

#### Evite vazamentos de memória

```cpp
// C: parear malloc com free
int* ptr = (int*)malloc(sizeof(int));
free(ptr);

// C++: parear new com delete
int* ptr = new int(42);
delete ptr;

// C++: prefira smart pointers
std::unique_ptr<int> ptr = std::make_unique<int>(42);
```

{% endstep %}

{% step %}

#### Use `override` em C++11+

```cpp
class Derivada : public Base {
    void metodo() override {  // Verifica se realmente sobrescreve
        // ...
    }
};
```

{% endstep %}
{% endstepper %}

## Vulnerabilidades Comuns

| Vulnerabilidade      | Descrição                                 | Mitigação                                  |
| -------------------- | ----------------------------------------- | ------------------------------------------ |
| Vazamento de memória | `new` sem `delete`                        | RAII, smart pointers                       |
| Double free          | Liberar mesma memória duas vezes          | Setar ponteiros para `nullptr` após delete |
| Dangling pointer     | Acessar ponteiro após liberação           | Smart pointers, validação                  |
| Stack overflow       | Recursão infinita                         | Limitar profundidade, usar iterativo       |
| Object slicing       | Atribuir objeto derivado a base por valor | Usar ponteiros ou referências              |

### Object Slicing (Exemplo)

```cpp
class Base {
public:
    virtual void funcao() { std::cout << "Base\n"; }
};

class Derivada : public Base {
public:
    void funcao() override { std::cout << "Derivada\n"; }
};

Derivada d;
Base b = d;      // Slicing: perde informações da derivada
b.funcao();      // "Base" (não polimórfico)

Base& ref = d;   // OK: referência
ref.funcao();    // "Derivada" (polimórfico)
```

## Resumo para Segurança

| Prática                     | Risco                             | Mitigação                                         |
| --------------------------- | --------------------------------- | ------------------------------------------------- |
| Ponteiros crus              | Vazamentos, double free, dangling | Smart pointers (C++)                              |
| Recursão sem limite         | Stack overflow                    | Limitar profundidade, usar iterativo              |
| Funções variádicas          | Acesso incorreto a argumentos     | Verificar count, usar `va_list` corretamente      |
| Herança e polimorfismo      | Object slicing                    | Usar ponteiros/referências                        |
| Construtores sem `explicit` | Conversões implícitas indesejadas | Usar `explicit` para construtores de um parâmetro |

## Recursos Adicionais

* Manual: `man g++`, `man gdb`
* Documentação: [cppreference.com - Classes](https://en.cppreference.com/w/cpp/language/classes)
* Livro: "The C++ Programming Language" (Bjarne Stroustrup)
* Livro: "Effective Modern C++" (Scott Meyers)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/programacao-e-linguagens/c-and-c++/3.-funcoes-and-classes-and-estruturas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
