S SmartDocs
Série: C++ cpp 237 linhas · Atualizado 2026-04-03

namespaces.cpp

C++/Part4_現代CPP/Ch19_命名空間與多檔案專案/namespaces.cpp

// Ch19 範例:命名空間(Namespace)
// 編譯:g++ -std=c++17 -Wall -o namespaces namespaces.cpp

#include <iostream>
#include <string>
#include <cmath>

// ============================================================
// 1. 基本命名空間定義
// ============================================================

// 數學相關的命名空間
namespace Math {
    constexpr double PI = 3.14159265358979;
    constexpr double E  = 2.71828182845905;

    double circleArea(double radius) {
        return PI * radius * radius;
    }

    double circlePerimeter(double radius) {
        return 2.0 * PI * radius;
    }

    double power(double base, int exp) {
        double result = 1.0;
        for (int i = 0; i < exp; ++i)
            result *= base;
        return result;
    }
}

// 圖形相關的命名空間
namespace Graphics {
    struct Color {
        int r, g, b;
    };

    struct Point {
        double x, y;
    };

    void printColor(const Color& c) {
        std::cout << "RGB(" << c.r << ", " << c.g << ", " << c.b << ")\n";
    }

    double distance(const Point& a, const Point& b) {
        double dx = a.x - b.x;
        double dy = a.y - b.y;
        return std::sqrt(dx * dx + dy * dy);
    }
}

// 工具相關的命名空間
namespace Utils {
    std::string repeat(const std::string& s, int n) {
        std::string result;
        for (int i = 0; i < n; ++i)
            result += s;
        return result;
    }

    std::string toUpper(std::string s) {
        for (auto& c : s)
            c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
        return s;
    }

    void printSeparator(int width = 50) {
        std::cout << std::string(static_cast<size_t>(width), '=') << "\n";
    }
}

// ============================================================
// 2. 巢狀命名空間
// ============================================================

// 傳統寫法
namespace Company {
    namespace Engine {
        namespace Physics {
            double gravity = 9.8;
            double calculateForce(double mass) {
                return mass * gravity;
            }
        }
    }
}

// C++17 簡化語法 — 效果完全相同
namespace Company::Engine::Audio {
    int sampleRate = 44100;
    void playSoundEffect(const std::string& name) {
        std::cout << "播放音效:" << name
                  << "(取樣率:" << sampleRate << " Hz)\n";
    }
}

// ============================================================
// 3. 匿名命名空間 — 限制可見性到本編譯單元
// ============================================================
namespace {
    int internalCounter = 0;

    void incrementCounter() {
        ++internalCounter;
    }

    // 這些函式與變數只在本檔案中可見,等同於 static
}

// ============================================================
// 4. 可以在多處擴充同一個命名空間
// ============================================================
namespace Math {
    // 在同一個命名空間中新增更多內容
    int factorial(int n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);
    }

    bool isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; ++i)
            if (n % i == 0) return false;
        return true;
    }
}

// ============================================================
// 主程式
// ============================================================
int main() {
    // --- 1. 使用完整限定名稱 ---
    Utils::printSeparator();
    std::cout << "【1. 基本命名空間 — 完整限定名稱】\n";
    Utils::printSeparator();

    std::cout << "圓周率 π = " << Math::PI << "\n";
    std::cout << "自然常數 e = " << Math::E << "\n";
    std::cout << "半徑 5 的圓面積 = " << Math::circleArea(5.0) << "\n";
    std::cout << "半徑 5 的圓周長 = " << Math::circlePerimeter(5.0) << "\n";
    std::cout << "2^10 = " << Math::power(2.0, 10) << "\n";
    std::cout << "5! = " << Math::factorial(5) << "\n";
    std::cout << "17 是質數?" << (Math::isPrime(17) ? "是" : "否") << "\n";
    std::cout << "\n";

    // --- 2. using 宣告 — 引入特定名稱(推薦做法)---
    Utils::printSeparator();
    std::cout << "【2. using 宣告】\n";
    Utils::printSeparator();

    using Graphics::Point;      // 只引入 Point
    using Graphics::distance;   // 只引入 distance

    Point p1{0.0, 0.0};
    Point p2{3.0, 4.0};
    std::cout << "點 (0,0) 到 (3,4) 的距離 = " << distance(p1, p2) << "\n";

    Graphics::Color red{255, 0, 0};
    Graphics::printColor(red);
    std::cout << "\n";

    // --- 3. using 指令 — 引入整個命名空間(在 .cpp 中的函式內使用尚可)---
    {
        Utils::printSeparator();
        std::cout << "【3. using 指令(限制在區塊內)】\n";
        Utils::printSeparator();

        using namespace Utils;
        std::cout << repeat("C++ ", 5) << "\n";
        std::cout << toUpper("hello world") << "\n";
        std::cout << "\n";
    }
    // 離開區塊後,Utils 的名稱不再直接可見

    // --- 4. 巢狀命名空間 ---
    Utils::printSeparator();
    std::cout << "【4. 巢狀命名空間】\n";
    Utils::printSeparator();

    // 傳統巢狀命名空間
    double mass = 10.0;
    std::cout << "重力加速度 = " << Company::Engine::Physics::gravity << " m/s²\n";
    std::cout << mass << " kg 的重力 = "
              << Company::Engine::Physics::calculateForce(mass) << " N\n";

    // C++17 巢狀命名空間
    Company::Engine::Audio::playSoundEffect("爆炸");
    std::cout << "\n";

    // --- 5. 命名空間別名 ---
    Utils::printSeparator();
    std::cout << "【5. 命名空間別名】\n";
    Utils::printSeparator();

    namespace CEP = Company::Engine::Physics;
    namespace CEA = Company::Engine::Audio;

    std::cout << "(透過別名)重力 = " << CEP::gravity << " m/s²\n";
    CEA::playSoundEffect("雷射");
    std::cout << "\n";

    // --- 6. 匿名命名空間 ---
    Utils::printSeparator();
    std::cout << "【6. 匿名命名空間】\n";
    Utils::printSeparator();

    std::cout << "內部計數器初始值 = " << internalCounter << "\n";
    incrementCounter();
    incrementCounter();
    incrementCounter();
    std::cout << "遞增三次後 = " << internalCounter << "\n";
    std::cout << "\n";

    // --- 7. std 命名空間 ---
    Utils::printSeparator();
    std::cout << "【7. std 命名空間】\n";
    Utils::printSeparator();

    std::cout << "C++ 標準函式庫的所有內容都在 std 命名空間中\n";
    std::cout << "std::string, std::vector, std::cout 等\n";
    std::cout << "永遠不要在自己的程式碼中向 std 命名空間加入任何東西\n";
    std::cout << "\n";

    // --- 總結 ---
    Utils::printSeparator();
    std::cout << "【總結】\n";
    Utils::printSeparator();
    std::cout << "1. namespace 將相關程式碼分組,避免名稱衝突\n";
    std::cout << "2. C++17 允許 namespace A::B::C 的簡化巢狀語法\n";
    std::cout << "3. using 宣告比 using 指令更安全\n";
    std::cout << "4. 匿名命名空間限制可見性到本檔案\n";
    std::cout << "5. 命名空間別名簡化冗長的名稱\n";

    return 0;
}

Artigos relacionados