C++ é uma linguagem de programação multiparadigma com gerenciamento manual de memória, combinando programação procedural, orientada a objetos e genérica. No desenvolvimento móvel, o C++ é usado através do Android NDK para portar bibliotecas e através dos motores de jogos Unity e Unreal Engine para criar jogos multiplataforma. De acordo com o TIOBE (2026), o C++ está entre as 5 linguagens mais populares entre desenvolvedores profissionais.
Pontos principais
C++ é uma linguagem de programação criada por Bjarne Stroustrup em 1985 como uma extensão da linguagem C com suporte a classes. O C++ fornece acesso direto à memória através de ponteiros, metaprogramação de modelos e herança múltipla. Os padrões C++17 e C++20 adicionaram corrotinas, conceitos e ranges.
Ao contrário de Java e Kotlin, o C++ não possui coletor de lixo — o desenvolvedor gerencia manualmente a alocação e liberação de memória através dos operadores new e delete. Isso dá controle total sobre o desempenho, mas exige disciplina. De acordo com a JetBrains Developer Survey (2025), 42% dos desenvolvedores C++ usam a linguagem na indústria de jogos.
Os padrões C++ evoluem a cada três anos: C++11 (lambdas, auto, unique_ptr), C++14 (lambdas genéricas), C++17 (if constexpr, filesystem), C++20 (módulos, corrotinas, conceitos). Os compiladores Clang e GCC suportam todos os padrões atuais, e o Android NDK usa o Clang do toolchain LLVM.
A principal diferença entre C++ e as linguagens JVM é o gerenciamento manual de memória e a compilação direta para código de máquina. Java e Kotlin funcionam sobre uma máquina virtual com coleta automática de lixo. O código C++ compila em um binário nativo para uma arquitetura específica — ARM, x86 ou RISC-V.
| Critério | C++ | Java / Kotlin |
|---|---|---|
| Gerenciamento de memória | Manual (new/delete, RAII) | Automático (coletor de lixo) |
| Compilação | Código de máquina nativo | Bytecode JVM / ART |
| Desempenho | Máximo (abstrações de custo zero) | Alto com pausas GC |
| Uso no desenvolvimento móvel | NDK, jogos, bibliotecas | Aplicativos UI, lógica de negócios |
| Compilação | CMake, NDK Build, Gradle + NDK | Gradle, Maven |
| Multiplataforma | Compilar para cada plataforma | JVM / ART em toda parte |
Android NDK (Native Development Kit) é um kit de ferramentas do Google para escrever partes de aplicativos Android em C e C++. O NDK inclui um toolchain baseado em Clang, arquivos de cabeçalho do sistema Android e bibliotecas de depuração e perfilamento. A versão r27 (2025) suporta C++20 e usa LLVM 18.
O NDK compila código C++ em bibliotecas dinâmicas .so para as arquiteturas ARM64, ARM32, x86 e x86_64. Um aplicativo Java ou Kotlin carrega essas bibliotecas via System.loadLibrary() e chama funções nativas através do JNI. De acordo com o Google, o NDK foi baixado mais de 5 milhões de vezes.
Um projeto típico com Android NDK contém a pasta app/src/main/cpp/ com arquivos fonte C++, CMakeLists.txt para compilação e uma classe Java com declaração de métodos nativos. O Gradle conecta o NDK através do bloco externalNativeBuild no build.gradle.
// native-lib.cpp — método JNI simples para Android
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_app_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /*thiz*/) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}O código declara uma função JNI com o nome completo Java_com_example_app_MainActivity_stringFromJNI — esta é a convenção de nomenclatura JNI. A função recebe um ponteiro para JNIEnv (o ambiente de execução) e jobject (a instância da classe chamadora). env->NewStringUTF cria uma string Java a partir de uma string C++.
O Android suporta vários ABI (Application Binary Interface): arm64-v8a (dispositivos ARM de 64 bits, 99% dos smartphones modernos), armeabi-v7a (ARM de 32 bits, dispositivos antigos), x86_64 (emuladores). O NDK permite compilar .so para cada arquitetura através de filtros ABI no build.gradle.
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}C++ é a linguagem principal dos motores de jogos. O Unreal Engine usa C++ para todo o código do jogo, enquanto a Unity usa C++ no núcleo do motor para renderização e física. Mesmo se um desenvolvedor escrever em C# na Unity, internamente o C++ gerencia gráficos, som e cálculos físicos.
O Unreal Engine é construído sobre C++ desde o início. O código da lógica do jogo é escrito em C++ usando macros UHT (Unreal Header Tool) para integração com Blueprints — um sistema de scripting visual. As classes herdam dos tipos base AActor, UObject, UGameInstance com letras de prefixo U, A, F.
// Classe de personagem no Unreal Engine usando C++
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
UCLASS()
class AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere, Category = "Movement")
float MoveSpeed = 600.0f;
protected:
void SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) override;
};As macros UCLASS() e UPROPERTY() fazem parte do sistema de reflexão do Unreal Engine. O UHT (Unreal Header Tool) gera código C++ a partir de arquivos de cabeçalho para serialização, blueprints e replicação de rede. MoveSpeed é exibido no editor via UPROPERTY(EditAnywhere).
Unity usa C# para a lógica do jogo, mas C++ é usado em Native Plugins — bibliotecas .so para Android e .bundle para iOS. Através do Android NDK, é possível integrar SDKs C++ para redes de anúncios, análise ou portar bibliotecas C++ de jogos de desktop.
using System.Runtime.InteropServices;
using UnityEngine;
public class NativeBridge : MonoBehaviour
{
const string LIB_NAME = "native_plugin";
[DllImport(LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int ProcessFrame(
int width, int height,
IntPtr pixelData
);
void Update()
{
int result = ProcessFrame(Screen.width, Screen.height, IntPtr.Zero);
Debug.Log("Frame processed: " + result);
}
}Neste exemplo, o C# faz marshaling de uma chamada para a função C++ ProcessFrame via P/Invoke. O atributo DllImport especifica o nome da biblioteca .so. A função C++ processa o quadro em tempo real e retorna o resultado. Esta abordagem é usada para pós-efeitos e visão computacional.
JNI (Java Native Interface) é o mecanismo padrão para chamar código C/C++ de Java ou Kotlin. No Android, JNI é a única maneira de transferir dados entre a máquina virtual ART e uma biblioteca nativa. Cada chamada JNI tem sobrecarga, portanto os dados devem ser transferidos em lotes em vez de um campo de cada vez.
JNIEnv é um ponteiro para a tabela de funções JNI. env->FindClass carrega uma classe Java, env->GetMethodID obtém um identificador de método, env->CallVoidMethod o invoca. Para strings, use GetStringUTFChars e ReleaseStringUTFChars. JNI também suporta referências globais e fracas para objetos Java.
// Passar array de bytes de C++ para Java via JNI
extern "C" JNIEXPORT void JNICALL
Java_com_example_app_ImageProcessor_processArray(
JNIEnv *env, jobject /*thiz*/,
jbyteArray input, jint length) {
jbyte *buffer = env->GetByteArrayElements(input, nullptr);
jsize size = env->GetArrayLength(input);
for (jsize i = 0; i < size; ++i) {
buffer[i] = buffer[i] ^ 0xFF; // inverter bytes
}
env->ReleaseByteArrayElements(input, buffer, JNI_COMMIT);
}GetByteArrayElements obtém um ponteiro para o array de bytes Java. JNI_COMMIT em ReleaseByteArrayElements copia as alterações de volta para o array Java sem liberar memória. O processamento do loop for é executado na CPU com máximo desempenho C++ sem pausas GC.
O principal perigo do JNI são vazamentos de referências globais. Cada NewGlobalRef deve ser liberado via DeleteGlobalRef. Referências locais (retornadas por FindClass, NewStringUTF) são liberadas automaticamente ao retornar da função nativa. Para chamadas intensivas, use PushLocalFrame / PopLocalFrame.
CMake é a principal ferramenta de compilação para C++ no Android NDK. O CMakeLists.txt descreve os alvos de compilação, bibliotecas e dependências. O Gradle invoca o CMake através do externalNativeBuild, passando caminhos para o NDK e toolchain. Uma alternativa é o NDK Build baseado em Android.mk e Application.mk.
CMake 3.22+ suporta predefinições (CMakePresets.json) para diferentes configurações: debug, release, profile com diferentes flags de otimização. Para Android, usa-se o toolchain android.toolchain.cmake do NDK, fornecido automaticamente pelo Gradle durante a compilação.
# CMakeLists.txt para projeto Android NDK
cmake_minimum_required(VERSION 3.22)
project("native-lib")
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/image_utils.cpp
)
target_include_directories(
native-lib PRIVATE
src/main/cpp/include
)
target_link_libraries(
native-lib
android
log
${CMAKE_SOURCE_DIR}/libs/libjpeg.a
)
set_target_properties(
native-lib PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
)add_library(SHARED) cria uma biblioteca .so. target_link_libraries vincula as bibliotecas do sistema android (para JNI) e log (para __android_log_print). A biblioteca estática libjpeg.a é vinculada para manipulação de imagens JPEG. CXX_STANDARD 20 ativa o suporte a C++20.
vcpkg é um gerenciador de pacotes para C++ da Microsoft que suporta Android NDK como plataforma alvo. Através do vcpkg, é possível instalar Boost, OpenCV, SQLite, nlohmann-json e outras bibliotecas compiladas para Android ABI. O Vcpkg integra-se com CMake via CMAKE_TOOLCHAIN_FILE.
C++ oferece desempenho máximo em dispositivos móveis graças à compilação em código ARM nativo e à ausência de coletor de lixo. De acordo com testes do Google (Android Performance Patterns, 2024), o código JNI em C++ executa 3–10 vezes mais rápido que o código Java equivalente para tarefas com cálculos intensivos.
Fatores-chave do desempenho do C++ em plataformas móveis: localidade de cache (disposição contígua de memória), instruções SIMD NEON para ARM, comunicação JNI assíncrona através de filas de mensagens. NEON é a extensão SIMD da ARM, processando 128 bits de dados em uma única instrução, indispensável para processamento de áudio, vídeo e imagens.
// Processamento SIMD de array via NEON intrinsics
#include <arm_neon.h>
void process_audio_neon(float *data, size_t n) {
for (size_t i = 0; i < n; i += 4) {
float32x4_t vec = vld1q_f32(&data[i]);
float32x4_t result = vmulq_f32(vec, vdupq_n_f32(0.5f));
vst1q_f32(&data[i], result);
}
}vld1q_f32 carrega 4 floats da memória em um registrador NEON de 128 bits. vmulq_f32 multiplica todos os 4 elementos por 0.5 em um ciclo. vst1q_f32 armazena o resultado de volta. Sem SIMD, o mesmo loop executaria 4 multiplicações sequencialmente — o NEON oferece até 4x de aceleração para tais operações.
| Operação | C++ (ms) | Java/Kotlin (ms) | Aceleração |
|---|---|---|---|
| Processamento de imagem 1920x1080 | 12 | 45 | 3.75x |
| Transformada Rápida de Fourier (FFT) | 8 | 34 | 4.25x |
| Criptografia AES-256 de bloco 1MB | 3 | 18 | 6x |
| Compressão de dados ZLIB | 5 | 22 | 4.4x |
O primeiro e mais perigoso erro são vazamentos de memória. Cada new deve ter um delete, cada new[] deve ter um delete[]. Em dispositivos móveis com RAM limitada, qualquer vazamento leva a OOM (Out Of Memory) e falha do aplicativo. Use RAII através de ponteiros inteligentes: std::unique_ptr, std::shared_ptr, std::weak_ptr.
O segundo erro é ignorar a compatibilidade ABI. Uma biblioteca compilada para armeabi-v7a não carregará em um dispositivo ARM64. Sempre especifique abiFilters no build.gradle e teste em dispositivos reais, não apenas no emulador x86_64. Use Android App Bundle para filtragem automática de ABI.
O terceiro erro típico são chamadas JNI frequentes. Cada transição entre Java e C++ custa cerca de 50–100 ns. Se você processar um array de 10000 elementos um por um via JNI, a sobrecarga excede o trabalho útil. Passe arrays inteiros de uma vez e processe-os no lado C++.
Problemas de threading são outro erro frequente. C++ pode iniciar std::thread, mas o JNI só pode ser acessado de threads criadas pelo Java. Para chamar métodos Java de uma thread C++, use AttachCurrentThread / DetachCurrentThread através do JNI.
// Chamar Java corretamente de uma thread C++
JavaVM *g_vm; // ponteiro global obtido no JNI_OnLoad
void background_task() {
JNIEnv *env;
jint res = g_vm->AttachCurrentThread(&env, nullptr);
if (res == JNI_OK) {
jclass clazz = env->FindClass("com/example/App");
jmethodID mid = env->GetStaticMethodID(clazz, "onProgress", "(I)V");
env->CallStaticVoidMethod(clazz, mid, 100);
g_vm->DetachCurrentThread();
}
}Perguntas frequentes
Android NDK (Native Development Kit) é um kit de ferramentas para escrever partes de aplicativos em C ou C++. É usado para tarefas críticas de desempenho, portar bibliotecas C/C++ para Android e implementar código multiplataforma para Unity e Unreal Engine.
Na Unity, o código da lógica do jogo é escrito em C#, mas C++ é usado em conjunto com Android NDK para plugins, aceleração de hardware, portar bibliotecas C++ próprias e integrar SDKs nativos para publicidade e análise.
CMakeLists.txt descreve arquivos fonte, bibliotecas e flags de compilação. A configuração mínima inclui add_library para compilar .so e target_link_libraries para vincular o log do Android e outras bibliotecas do sistema.
JNI (Java Native Interface) é a camada entre o código Java/Kotlin de um aplicativo Android e a biblioteca C++. Se C++ é chamado de Java, JNI é obrigatório. Você pode escrever código C++ inteiramente através do NDK, mas o ponto de entrada geralmente é uma Activity Java que chama funções nativas.
C++ é justificado para jogos, processamento de áudio/vídeo em tempo real, visão computacional, criptografia, simulações físicas e portar bibliotecas de outras plataformas. Para um aplicativo UI comum, Kotlin é mais eficiente e simples.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.