---
title: "Guia de Migração: C++ para Zig"
url: "https://ziglang.com.br/tutoriais/guia-de-migra%C3%A7%C3%A3o-c-para-zig/"
markdown_url: "https://ziglang.com.br/tutoriais/guia-de-migra%C3%A7%C3%A3o-c-para-zig.MD"
description: "Guia técnico para migrar código C++ para Zig. Conversão de classes, templates, RAII, exceções, STL, smart pointers e padrões orientados a objetos para equivalentes Zig."
date: "2026-02-21"
author: "Zig Brasil"
---

# Guia de Migração: C++ para Zig

Guia técnico para migrar código C++ para Zig. Conversão de classes, templates, RAII, exceções, STL, smart pointers e padrões orientados a objetos para equivalentes Zig.


## Introdução

Migrar de C++ para Zig é uma transformação significativa. C++ é uma linguagem complexa com herança, templates, exceções, RAII via destrutores, e uma Standard Template Library rica. Zig substitui toda essa complexidade por um conjunto menor de primitivas mais poderosas.

Este guia cobre a conversão dos padrões mais comuns de C++ para Zig. Para comparação detalhada, veja [Zig vs C++](/artigos/zig-vs-cpp/).

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja [Como Instalar Zig](/tutoriais/como-instalar-zig/)
- Conhecimento de C++
- Familiaridade básica com Zig. Consulte [Introdução ao Zig](/tutoriais/introducao-ao-zig/)

## Classes para Structs

### C++

```cpp
class Vetor3D {
private:
    double x_, y_, z_;
public:
    Vetor3D(double x, double y, double z) : x_(x), y_(y), z_(z) {}

    double magnitude() const {
        return std::sqrt(x_*x_ + y_*y_ + z_*z_);
    }

    Vetor3D operator+(const Vetor3D& outro) const {
        return Vetor3D(x_ + outro.x_, y_ + outro.y_, z_ + outro.z_);
    }
};
```

### Zig

```zig
const std = @import("std");

const Vetor3D = struct {
    x: f64,
    y: f64,
    z: f64,

    pub fn criar(x: f64, y: f64, z: f64) Vetor3D {
        return .{ .x = x, .y = y, .z = z };
    }

    pub fn magnitude(self: Vetor3D) f64 {
        return std.math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z);
    }

    pub fn somar(self: Vetor3D, outro: Vetor3D) Vetor3D {
        return .{
            .x = self.x + outro.x,
            .y = self.y + outro.y,
            .z = self.z + outro.z,
        };
    }
};
```

Em Zig, não há sobrecarga de operadores. Use métodos com nomes descritivos. Não há construtores — use funções estáticas como `criar()` ou `init()`.

## Templates para Comptime

### C++

```cpp
template<typename T>
class Pilha {
    std::vector<T> items;
public:
    void push(const T& item) { items.push_back(item); }
    T pop() {
        T item = items.back();
        items.pop_back();
        return item;
    }
    bool empty() const { return items.empty(); }
};

// Uso
Pilha<int> pilha;
pilha.push(42);
```

### Zig

```zig
fn Pilha(comptime T: type) type {
    return struct {
        items: std.ArrayList(T),

        const Self = @This();

        pub fn init(allocator: std.mem.Allocator) Self {
            return .{ .items = std.ArrayList(T).init(allocator) };
        }

        pub fn deinit(self: *Self) void {
            self.items.deinit();
        }

        pub fn push(self: *Self, item: T) !void {
            try self.items.append(item);
        }

        pub fn pop(self: *Self) ?T {
            return self.items.popOrNull();
        }

        pub fn empty(self: Self) bool {
            return self.items.items.len == 0;
        }
    };
}

// Uso
var pilha = Pilha(i32).init(allocator);
defer pilha.deinit();
try pilha.push(42);
```

## RAII e Destrutores para defer

### C++

```cpp
class Arquivo {
    FILE* handle;
public:
    Arquivo(const char* path) : handle(fopen(path, "r")) {
        if (!handle) throw std::runtime_error("Erro ao abrir");
    }
    ~Arquivo() {
        if (handle) fclose(handle);
    }
    // Move-only
    Arquivo(Arquivo&& other) noexcept : handle(other.handle) {
        other.handle = nullptr;
    }
};

void processar() {
    Arquivo f("dados.txt");  // destrutor chamado automaticamente
}
```

### Zig

```zig
const Arquivo = struct {
    handle: std.fs.File,

    pub fn abrir(caminho: []const u8) !Arquivo {
        return .{
            .handle = try std.fs.cwd().openFile(caminho, .{}),
        };
    }

    pub fn fechar(self: *Arquivo) void {
        self.handle.close();
    }
};

fn processar() !void {
    var f = try Arquivo.abrir("dados.txt");
    defer f.fechar(); // equivalente ao destrutor
}
```

Em Zig, `defer` substitui RAII. É explícito — o programador decide quando e o que é liberado. `errdefer` executa apenas em caso de erro. Veja [Padrões Errdefer](/receitas/zig-errdefer-pattern/).

## Exceções para Error Unions

### C++

```cpp
double dividir(double a, double b) {
    if (b == 0) throw std::invalid_argument("Divisão por zero");
    return a / b;
}

try {
    double resultado = dividir(10, 0);
} catch (const std::invalid_argument& e) {
    std::cerr << e.what() << std::endl;
}
```

### Zig

```zig
fn dividir(a: f64, b: f64) !f64 {
    if (b == 0) return error.DivisaoPorZero;
    return a / b;
}

const resultado = dividir(10, 0) catch |err| {
    std.debug.print("Erro: {}\n", .{err});
    return;
};
```

Veja [Error Sets Customizados](/receitas/zig-error-set-customizado/) e [Error Logging](/receitas/zig-error-logging/).

## Smart Pointers para Allocators

### C++

```cpp
auto ptr = std::make_unique<MinhaClasse>(args...);
auto shared = std::make_shared<MinhaClasse>(args...);
std::weak_ptr<MinhaClasse> weak = shared;
```

### Zig

```zig
// unique_ptr equivalente
const ptr = try allocator.create(MinhaStruct);
defer allocator.destroy(ptr);

// Não há shared_ptr nativo — implementar se necessário
// ou usar arena allocator para gerenciamento em grupo
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
```

Zig não tem smart pointers. O gerenciamento é via allocators e `defer`. Para compartilhamento, use arena allocators ou implemente contagem de referências manualmente. Veja [ArenaAllocator](/receitas/zig-arena-allocator/).

## STL Containers para std de Zig

| C++ (STL) | Zig (std) |
|-----------|-----------|
| `std::vector<T>` | `std.ArrayList(T)` |
| `std::array<T,N>` | `[N]T` |
| `std::string` | `[]const u8` / `std.ArrayList(u8)` |
| `std::unordered_map<K,V>` | `std.HashMap(K,V,...)` |
| `std::map<K,V>` | `std.TreeMap` (ou sorted array) |
| `std::optional<T>` | `?T` |
| `std::variant<A,B,C>` | `union(enum) { a: A, b: B, c: C }` |

## Herança para Composição

### C++

```cpp
class Forma {
public:
    virtual double area() const = 0;
    virtual ~Forma() = default;
};

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

### Zig

```zig
// Opção 1: Comptime (polimorfismo estático)
fn calcularArea(forma: anytype) f64 {
    return forma.area();
}

const Circulo = struct {
    raio: f64,
    pub fn area(self: Circulo) f64 {
        return std.math.pi * self.raio * self.raio;
    }
};

// Opção 2: Interface manual (polimorfismo dinâmico)
const Forma = struct {
    ptr: *anyopaque,
    areaFn: *const fn (*anyopaque) f64,

    pub fn area(self: Forma) f64 {
        return self.areaFn(self.ptr);
    }
};
```

## Namespaces

### C++

```cpp
namespace math {
    namespace linear {
        class Matrix { /* ... */ };
    }
}
```

### Zig

```zig
// math/linear.zig
pub const Matrix = struct {
    // ...
};

// main.zig
const linear = @import("math/linear.zig");
const m = linear.Matrix{};
```

Zig usa o sistema de arquivos como namespaces. Cada arquivo é um struct implícito.

## Testes

### C++

```cpp
// Com Google Test
TEST(CalculadoraTest, Soma) {
    EXPECT_EQ(soma(2, 3), 5);
}
```

### Zig

```zig
test "soma" {
    try std.testing.expectEqual(@as(i32, 5), soma(2, 3));
}
```

Veja [Testes Unitários Básicos](/receitas/zig-teste-unitario-basico/) e [Testes com Allocator](/receitas/zig-teste-com-allocator/).

## Conclusão

A migração de C++ para Zig simplifica o código eliminando camadas de abstração (herança, templates complexos, exceções). O resultado é código mais previsível, mais fácil de entender e debugar, com performance equivalente ou superior.

Para build system, veja [Migrar de CMake para build.zig](/tutoriais/migrar-cmake-para-build-zig/). Para a estratégia geral, consulte [Guia de Migração: C para Zig](/tutoriais/migrar-de-c-para-zig/) (muitos padrões se aplicam).
