C++ — یک زبان برنامهنویسی چندالگویی با مدیریت دستی حافظه است که برنامهنویسی رویهای، شیءگرا و عمومی را ترکیب میکند. در توسعه موبایل، C++ از طریق Android NDK برای انتقال کتابخانهها و از طریق موتورهای بازی Unity و Unreal Engine برای ایجاد بازیهای چندسکویی استفاده میشود. طبق TIOBE (2026)، C++ در بین پنج زبان محبوب در میان توسعهدهندگان حرفهای قرار دارد.
نکات اصلی
C++ — زبان برنامهنویسی ایجاد شده توسط بیارنه استراستروپ در سال ۱۹۸۵ به عنوان توسعه زبان C با پشتیبانی از کلاسها. C++ دسترسی مستقیم به حافظه را از طریق اشارهگرها، فرابرنامهنویسی قالبی و وراثت چندگانه فراهم میکند. استانداردهای C++17 و C++20 کوروتینها، کانسپتها و رنجها را اضافه کردند.
برخلاف Java و Kotlin، C++ زبالهروب ندارد — توسعهدهنده به صورت دستی تخصیص و آزادسازی حافظه را از طریق عملگرهای new و delete مدیریت میکند. این امر کنترل کامل بر عملکرد را فراهم میکند اما نیازمند انضباط است. طبق JetBrains Developer Survey (2025)، ۴۲٪ از توسعهدهندگان C++ از این زبان در صنعت بازی استفاده میکنند.
استانداردهای C++ هر سه سال یکبار تکامل مییابند: C++11 (لامبداها، auto، unique_ptr)، C++14 (لامبداهای عمومی)، C++17 (if constexpr، filesystem)، C++20 (ماژولها، کوروتینها، کانسپتها). کامپایلرهای Clang و GCC از همه استانداردهای فعلی پشتیبانی میکنند و برای Android NDK از Clang از زنجیره ابزار LLVM استفاده میشود.
تفاوت اصلی C++ با زبانهای JVM — مدیریت دستی حافظه و کامپایل مستقیم به کد ماشین است. Java و Kotlin روی ماشین مجازی با جمعآوری خودکار زباله کار میکنند. کد C++ به یک فایل باینری بومی برای معماری خاص — ARM، x86 یا RISC-V کامپایل میشود.
| معیار | C++ | Java / Kotlin |
|---|---|---|
| مدیریت حافظه | دستی (new/delete, RAII) | خودکار (Garbage Collector) |
| کامپایل | کد ماشین بومی | بایتکد JVM / ART |
| عملکرد | حداکثر (zero-cost abstractions) | بالا با توقفهای GC |
| استفاده در توسعه موبایل | NDK، بازیها، کتابخانهها | برنامههای UI، منطق تجاری |
| ساخت | CMake، NDK Build، Gradle + NDK | Gradle، Maven |
| چندسکویی | کامپایل برای هر سکو | JVM / ART همهجا |
Android NDK (Native Development Kit) — مجموعه ابزارهای Google برای نوشتن بخشهایی از برنامه Android به زبان C و C++. NDK شامل زنجیره ابزار مبتنی بر Clang، فایلهای هدر سیستمی Android، کتابخانههای اشکالزدایی و پروفایلینگ است. نسخه r27 (2025) از C++20 پشتیبانی میکند و از LLVM 18 استفاده میکند.
NDK کد C++ را به کتابخانههای پویا .so برای معماریهای ARM64، ARM32، x86 و x86_64 کامپایل میکند. برنامه Java یا Kotlin این کتابخانهها را از طریق System.loadLibrary() بارگذاری میکند و توابع native را از طریق JNI فراخوانی میکند. طبق Google، NDK بیش از ۵ میلیون بار دانلود شده است.
یک پروژه معمولی با Android NDK شامل پوشه app/src/main/cpp/ با فایلهای منبع C++، CMakeLists.txt برای ساخت و کلاس Java با اعلام متدهای native است. Gradle NDK را از طریق بلوک externalNativeBuild در build.gradle متصل میکند.
// native-lib.cpp — یک متد ساده JNI برای 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());
}کد یک تابع JNI با نام کامل Java_com_example_app_MainActivity_stringFromJNI را اعلام میکند — این قرارداد نامگذاری JNI است. تابع یک اشارهگر به JNIEnv (محیط اجرا) و jobject (نمونه کلاس فراخوان) را دریافت میکند. env->NewStringUTF یک رشته Java از رشته C++ ایجاد میکند.
Android از چندین ABI (Application Binary Interface) پشتیبانی میکند: arm64-v8a (دستگاههای ۶۴ بیتی ARM، ۹۹٪ گوشیهای هوشمند مدرن)، armeabi-v7a (ARM ۳۲ بیتی، دستگاههای قدیمی)، x86_64 (شبیهسازها). NDK امکان ساخت .so برای هر معماری را از طریق فیلترهای ABI در build.gradle فراهم میکند.
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}C++ — زبان اصلی موتورهای بازی است. Unreal Engine از C++ برای تمام کد بازی استفاده میکند و Unity از C++ در هسته موتور برای رندرینگ و فیزیک استفاده میکند. حتی اگر توسعهدهنده در Unity به زبان C# بنویسد، در پشت صحنه C++ گرافیک، صدا و محاسبات فیزیکی را مدیریت میکند.
Unreal Engine از پایه بر روی C++ ساخته شده است. کد منطق بازی به زبان C++ با استفاده از ماکروهای UHT (Unreal Header Tool) برای یکپارچهسازی با Blueprints — سیستم بصری اسکریپتنویسی نوشته میشود. کلاسها از انواع پایه AActor، UObject، UGameInstance با حروف پیشوند U، A، F ارثبری میکنند.
// کلاس کاراکتر در Unreal Engine به زبان 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;
};ماکروهای UCLASS() و UPROPERTY() — بخشی از سیستم بازتاب Unreal Engine هستند. UHT (Unreal Header Tool) کد C++ را از فایلهای هدر برای سریالسازی، بلوپرینتها و تکرار شبکه تولید میکند. MoveSpeed از طریق UPROPERTY(EditAnywhere) در ویرایشگر نمایش داده میشود.
Unity از C# برای منطق بازی استفاده میکند، اما C++ در Native Plugins — کتابخانههای .so برای Android و .bundle برای iOS به کار میرود. از طریق Android NDK میتوان C++ SDK شبکههای تبلیغاتی، تجزیه و تحلیل را متصل کرد یا کتابخانه C++ را از بازیهای رومیزی منتقل کرد.
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);
}
}در این مثال، C# فراخوانی تابع C++ ProcessFrame را از طریق P/Invoke مارشال میکند. ویژگی DllImport نام کتابخانه .so را مشخص میکند. تابع C++ فریم را در زمان واقعی پردازش میکند و نتیجه را برمیگرداند. چنین رویکردی برای پساثرها و بینایی کامپیوتری استفاده میشود.
JNI (Java Native Interface) — مکانیزم استاندارد برای فراخوانی کد C/C++ از Java یا Kotlin است. در Android، JNI تنها راه انتقال داده بین ماشین مجازی ART و کتابخانه بومی است. هر فراخوانی JNI سربار دارد، بنابراین دادهها به صورت بستهای و نه تکتک فیلدها منتقل میشوند.
JNIEnv — اشارهگری به جدول توابع JNI است. env->FindClass کلاس Java را بارگذاری میکند، env->GetMethodID شناسه متد را میگیرد، env->CallVoidMethod آن را فراخوانی میکند. برای رشتهها از GetStringUTFChars و ReleaseStringUTFChars استفاده میشود. JNI همچنین از ارجاعهای سراسری و ضعیف به اشیاء Java پشتیبانی میکند.
// انتقال آرایه بایت از C++ به Java از طریق 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; // بایتها را معکوس میکنیم
}
env->ReleaseByteArrayElements(input, buffer, JNI_COMMIT);
}GetByteArrayElements اشارهگری به آرایه بایت Java میگیرد. JNI_COMMIT در ReleaseByteArrayElements تغییرات را بدون آزادسازی حافظه به آرایه Java برمیگرداند. پردازش حلقه for روی CPU با حداکثر عملکرد C++ بدون توقفهای GC انجام میشود.
خطر اصلی JNI — نشت ارجاعهای سراسری است. هر NewGlobalRef باید از طریق DeleteGlobalRef آزاد شود. ارجاعهای محلی (بازگشتی از FindClass، NewStringUTF) به طور خودکار هنگام بازگشت از تابع native حذف میشوند. برای فراخوانیهای فشرده از PushLocalFrame / PopLocalFrame استفاده کنید.
CMake — ابزار اصلی ساخت برای C++ در Android NDK است. CMakeLists.txt اهداف ساخت، کتابخانهها و وابستگیها را توصیف میکند. Gradle CMake را از طریق externalNativeBuild فراخوانی میکند و مسیرهای NDK و زنجیره ابزار را ارسال میکند. جایگزین — NDK Build مبتنی بر Android.mk و Application.mk.
CMake 3.22+ از پریستها (CMakePresets.json) برای تنظیمات مختلف پشتیبانی میکند: debug، release، profile با پرچمهای بهینهسازی متفاوت. برای Android از زنجیره ابزار android.toolchain.cmake از NDK استفاده میشود که توسط Gradle در هنگام ساخت به طور خودکار جایگزین میشود.
# CMakeLists.txt برای پروژه 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) یک کتابخانه .so ایجاد میکند. target_link_libraries کتابخانههای سیستمی android (برای JNI) و log (برای __android_log_print) را متصل میکند. کتابخانه ایستا libjpeg.a برای کار با تصاویر JPEG لینک میشود. CXX_STANDARD 20 پشتیبانی C++20 را فعال میکند.
vcpkg — مدیر بسته برای C++ از مایکروسافت که از Android NDK به عنوان سکوی هدف پشتیبانی میکند. از طریق vcpkg میتوان Boost، OpenCV، SQLite، nlohmann-json و سایر کتابخانههای کامپایل شده برای Android ABI را نصب کرد. Vcpkg از طریق CMAKE_TOOLCHAIN_FILE با CMake یکپارچه میشود.
C++ به لطف کامپایل به کد بومی ARM و عدم وجود زبالهروب، حداکثر عملکرد را در دستگاههای موبایل فراهم میکند. طبق آزمایشهای Google (Android Performance Patterns، ۲۰۲۴)، کد JNI در C++ برای وظایف با محاسبات فشرده ۳ تا ۱۰ برابر سریعتر از کد معادل Java اجرا میشود.
عوامل کلیدی عملکرد C++ در سکوهای موبایل: محلیبودن کش (قرارگیری دادهها در حافظه پیوسته)، دستورالعملهای SIMD NEON برای ARM، کار ناهمگام با JNI از طریق صفهای پیام. NEON — افزونه SIMD ARM که امکان پردازش ۱۲۸ بیت داده در یک دستورالعمل را فراهم میکند، برای پردازش صدا، ویدئو و تصاویر ضروری است.
// پردازش آرایه SIMD از طریق 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 ۴ عدد float را از حافظه به ثبات ۱۲۸ بیتی NEON بارگذاری میکند. vmulq_f32 هر ۴ عنصر را در یک سیکل در ۰.۵ ضرب میکند. vst1q_f32 نتیجه را برمیگرداند. بدون SIMD همان حلقه ۴ ضرب را متوالی انجام میداد — NEON برای چنین عملیاتی تا ۴x شتاب میدهد.
| عملیات | C++ (ms) | Java/Kotlin (ms) | شتاب |
|---|---|---|---|
| پردازش تصویر 1920x1080 | ۱۲ | ۴۵ | ۳.۷۵x |
| تبدیل سریع فوریه (FFT) | ۸ | ۳۴ | ۴.۲۵x |
| رمزگذاری AES-256 بلوک ۱MB | ۳ | ۱۸ | ۶x |
| فشردهسازی داده ZLIB | ۵ | ۲۲ | ۴.۴x |
اولین و خطرناکترین اشتباه — نشت حافظه. هر new باید delete داشته باشد، هر new[] — delete[]. در دستگاههای موبایل با RAM محدود، هر نشتی منجر به OOM (Out Of Memory) و سقوط برنامه میشود. از RAII از طریق اشارهگرهای هوشمند استفاده کنید: std::unique_ptr، std::shared_ptr، std::weak_ptr.
دومین اشتباه — نادیده گرفتن سازگاری ABI. کتابخانهای که برای armeabi-v7a کامپایل شده، روی دستگاه ARM64 بارگذاری نمیشود. همیشه abiFilters را در build.gradle مشخص کنید و روی دستگاههای واقعی تست کنید، نه فقط شبیهساز x86_64. از Android App Bundle برای فیلتر خودکار ABI استفاده کنید.
سومین اشتباه رایج — فراخوانیهای مکرر JNI. هر انتقال بین Java و C++ حدود ۵۰–۱۰۰ ns هزینه دارد. اگر آرایهای از ۱۰۰۰۰ عنصر را یکی یکی از طریق JNI پردازش کنید، سربار از کار مفید بیشتر میشود. دادهها را به صورت آرایههای کامل منتقل کنید و در سمت C++ پردازش کنید.
مشکلات چندنخی — یکی دیگر از اشتباهات رایج. C++ میتواند std::thread را راهاندازی کند، اما دسترسی به JNI فقط از نخی که توسط Java ایجاد شده امکانپذیر است. برای فراخوانی متدهای Java از نخ C++ از AttachCurrentThread / DetachCurrentThread از طریق JNI استفاده کنید.
// فراخوانی صحیح Java از نخ C++
JavaVM *g_vm; // اشارهگر سراسری، دریافت شده در 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();
}
}سوالات متداول
Android NDK (Native Development Kit) — مجموعه ابزاری برای نوشتن بخشهایی از برنامه به زبان C یا C++. از آن برای وظایف حیاتی از نظر عملکرد، انتقال کتابخانههای C/C++ به Android و پیادهسازی کد چندسکویی Unity و Unreal Engine استفاده میشود.
در Unity کد منطق بازی به زبان C# نوشته میشود، اما C++ در ترکیب با Android NDK برای پلاگینها، کار با شتابدهی سختافزاری، انتقال کتابخانههای اختصاصی C++ و یکپارچهسازی SDKهای بومی برای تبلیغات و تحلیل استفاده میشود.
CMakeLists.txt فایلهای منبع، کتابخانهها و پرچمهای کامپایل را توصیف میکند. پیکربندی حداقلی شامل add_library برای ساخت .so و target_link_libraries برای اتصال Android log و سایر کتابخانههای سیستمی است.
JNI (Java Native Interface) — لایه میانی بین کد Java/Kotlin برنامه Android و کتابخانه C++ است. اگر C++ از Java فراخوانی شود، JNI اجباری است. میتوان کد C++ را کاملاً از طریق NDK نوشت، اما نقطه ورود معمولاً یک Activity Java است که توابع native را فراخوانی میکند.
C++ برای بازیها، پردازش صدا/ویدئو در زمان واقعی، بینایی کامپیوتری، رمزنگاری، شبیهسازیهای فیزیکی و انتقال کتابخانهها از سکوهای دیگر توجیه دارد. برای یک برنامه UI معمولی، Kotlin کارآمدتر و سادهتر است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.