Diferenças entre C++ e Rust: Variáveis, Namespaces, Classes, Controle de Erros, Estruturas de Controle e Funções
C++ e Rust são linguagens de programação de sistemas poderosas, cada uma com suas próprias abordagens em relação a organização de código, manuseio de erros, e estruturas de controle. Abaixo está uma comparação detalhada entre os dois em aspectos fundamentais.
-
C++:
- Os arquivos são geralmente separados em
.cpp(implementação) e.hou.hpp(declarações de cabeçalho). - Isso permite separação entre interface e implementação.
-
util.cpp
void saudacao() { std::cout << "Ola" << std::endl; }
-
util.hpp
void saudacao();
-
main.cpp
#include "util.hpp" int main() { saudacao(); return 0; }
- Os arquivos são geralmente separados em
-
Rust:
- Tudo é feito em arquivos
.rs. - A separação entre módulos é feita por arquivos ou diretórios, e o sistema de módulos é integrado diretamente na linguagem.
-
util.rs
pub fn saudacao() { println!("Ola"); }
-
main.rs
mod util; fn main() { util::saudacao(); }
- Tudo é feito em arquivos
-
C++:
-
Normalmente você terá que fazer uma declaração explicita dos tipos e por padrão, as variáveis são editáveis;
-
É possível tornar uma variável inalterável tornando-a uma constante usando
const; -
Pode-se definir a variável automaticamente com
auto;int main() { int x = 5; // declaração explicita x = 10; const int y = 10; // constante auto z = 15; // definição automatica de tipo return 0; }
-
-
Rust:
-
A declaração é feita automaticamente com
let, funcionando como oautodo C++; -
Por padrão, as variáveis são imutáveis, promovendo maior segurança. Para torná-la mutável, usa-se
mut; -
Tipagem explícita é possível dessa forma:
let x: i32 = 5;fn main() { let x = 5; // imutável por padrão let mut y = 10; // mutável y = 15; let z: i32 = 15; // tipo explicitado }
-
-
C++:
-
Usa namespace para organizar código e using para facilitar o acesso:
namespace util { void saudacao() { std::cout << "Ola" << std::endl; } } int main() { util::saudacao(); return 0; }
-
-
Rust:
-
Usa módulos (
mod) eusepara importação:mod util { pub fn saudacao() { println!("Olá"); } } fn main() { util::saudacao(); }
-
-
C++:
-
Usa
classe você pode escolher se os atributos e funções são privados, protegidos ou públicos. -
Requer delete para liberar memória manualmente.
#include <iostream> #include <string> class Aplicacao { private: std::string nome; public: Aplicacao(std::string nomeApp) : nome(nomeApp) {} void run() { std::cout << "Executando: " << nome << std::endl; } }; int main() { Aplicacao* app = new Aplicacao("MeuPrograma"); app->run(); delete app; return 0; }
-
-
Rust:
-
Usa struct e impl para métodos.
-
Método new() inicializa a struct.
-
A alocação é feita de forma automática (stack).
-
Não precisa de algo como um delete – o sistema de ownership cuida disso.
struct Aplicacao { nome: String, } impl Aplicacao { fn new(nome: &str) -> Self { Aplicacao { nome: nome.to_string(), } } fn run(&self) { println!("Executando: {}", self.nome); } } fn main() { let app = Aplicacao::new("MeuPrograma"); app.run(); }
-
-
C++:
- Tudo é público por padrão, exceto dentro de
class, onde se definepublic,private,protected.
- Tudo é público por padrão, exceto dentro de
-
Rust:
- Tudo é privado por padrão.
- Para tornar algo público, usa-se
pub:
-
C++:
-
Suporta argumentos posicionais e valores padrão:
void saudacao(std::string nome = "Mundo") { std::cout << "Oi, " << nome << "!"; } saudacao(); // Oi, Mundo! saudacao("Joana"); // Oi, Joana!
-
-
Rust:
-
Não suporta valores padrão diretamente.
-
Para simular, usa
Option<T>:fn saudacao(nome: Option<&str>) { match nome { Some(n) => println!("Oi, {}!", n), None => println!("Oi, Mundo!"), } } saudacao(Some("Joana")); saudacao(None);
-
-
C++:
- Usa
try,catch,throw:
#include <iostream> #include <stdexcept> int executar() { // Simula erro throw std::runtime_error("Falha na execução"); return 0; } int main() { try { int status = executar(); std::cout << "Execução concluída com sucesso!\n"; return status; // código 0 } catch (const std::exception& e) { std::cerr << "Erro: " << e.what() << std::endl; return 1; // código de erro } }
- Usa
-
Rust:
- O rust retorna o Result no main e permite usar ? para propagar erros.
fn executar() -> Result<(), Box<dyn std::error::Error>> { // Simula erro Err("Falha na execução".into()) } fn main() -> Result<(), Box<dyn std::error::Error>> { executar()?; println!("Execução concluída com sucesso!"); Ok(()) }
-
Rust:
-
Usa
ResulteOption:fn ler_arquivo() -> Result<String, std::io::Error> { let conteudo = std::fs::read_to_string("teste.txt")?; Ok(conteudo) }
-
-
C++:
-
Usa
switch/case:switch(valor) { case 1: std::cout << "um"; break; case 2: std::cout << "dois"; break; default: std::cout << "outro"; }
-
-
Rust:
-
Usa
match, que é mais poderoso:match valor { 1 => println!("um"), 2 => println!("dois"), _ => println!("outro"), }
-
-
if:
- C++:
if (x > 0) {} - Rust:
if x > 0 {}
- C++:
-
for:
- C++:
for(int i = 0; i < 10; i++) {} - Rust:
for i in 0..10 {}
- C++:
-
while:
- C++:
while(x < 10) {} - Rust:
while x < 10 {}
- C++:
Rust introduz uma abordagem mais segura e moderna em comparação ao C++, forçando boas práticas como imutabilidade padrão, ausência de exceções e uso extensivo de enums e pattern matching. Por outro lado, C++ continua sendo mais flexível e familiar para desenvolvedores com experiência em linguagens clássicas.
Ambas têm seus pontos fortes, e a escolha depende das necessidades do projeto, do ambiente de execução e da experiência do programador.