首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ void 使用規範五大準則:從函數宣告到指標運算的完整規範

     編輯:C++ 入門

規範一:無回傳值函數必須宣告為 void

C 語言允許省略回傳型別 (預設 int),C++ 雖嚴格但編譯器不一定報警。為了可讀性、規範性與自文件化,所有函數必須明確宣告回傳型別:


// 錯誤範例
add(int a, int b) { return a + b; }  // 隱式 int

// 正確範例
int add(int a, int b) { return a + b; }
void printSum(int a, int b) { std::cout << a + b; }

規範二:無參數函數必須宣告為 void 參數列表


// C++ 標準寫法
int getValue(void) { return 42; }
getValue();    // 合法
getValue(1);   // 編譯錯誤

// 錯誤寫法
int getValue() { return 42; }  // C++ 中等同 void,但不明確

C 語言中 () 表示「未指定參數」,(void) 才是「無參數」。C++ 中兩者等價,但明確寫 void 更清晰。

規範三:謹慎使用 void 指標算術運算

ANSI 標準禁止


void* pvoid;
pvoid++;      // ANSI: 錯誤
pvoid += 1;   // ANSI: 錯誤

理由:算術運算需要知道型別大小 (sizeof(T)),void 無大小資訊。

GNU 延伸允許 (視同 char*)


pvoid++;      // GNU: 合法,位址 +1
pvoid += 1;   // GNU: 合法

跨平台相容寫法


// 明確轉換為 byte 指標運算
static_cast(pvoid)++;     // ANSI + GNU 皆合法
static_cast(pvoid) += 1; // 現代 C++ 推薦

實務建議:盡可能避免 void* 算術,改用模板或具體型別指標。

規範四:接受任意型別指標的函數參數應宣告為 void*

記憶體操作、序列化、泛型容器等「只關心位元組、不關心型別」的場景:


// 標準庫範例
void* memcpy(void* dest, const void* src, size_t n);
void* memset(void* ptr, int value, size_t n);

// 實際呼叫
int arr1[100], arr2[100];
memcpy(arr1, arr2, sizeof(arr1));  // int* 隱式轉 void*
memset(arr1, 0, sizeof(arr1));

若改為 char* 參數,呼叫端需強制轉換,破壞介面抽象層次。

規範五:void 不能代表真實變數


void a;              // 錯誤:無法建立 void 變數
void func(void a);   // 錯誤:參數不能是 void

void 體現抽象概念,如同抽象基類無法實例化。所有具體變數皆有具體型別。

綜合範例:正確的 void 使用模式


#include 
#include 

class Buffer {
    std::unique_ptr data_;
    size_t size_;
public:
    Buffer(size_t n) : data_(std::make_unique(n)), size_(n) {}
    
    // 規範四:接受任意資料指標
    void write(const void* src, size_t offset, size_t n) {
        if (offset + n > size_) throw std::out_of_range("Buffer overflow");
        std::memcpy(data_.get() + offset, src, n);  // 規範三:用 uint8_t* 運算
    }
    
    void read(void* dest, size_t offset, size_t n) const {
        if (offset + n > size_) throw std::out_of_range("Buffer overflow");
        std::memcpy(dest, data_.get() + offset, n);
    }
    
    // 規範一:無回傳值明確聲明
    void clear() { std::memset(data_.get(), 0, size_); }
    
    // 規範二:無參數明確聲明
    size_t capacity(void) const { return size_; }
};

現代 C++ 替代 void* 的方案

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景傳統 void*現代替代
泛型緩衝區void* datastd::span (C++20)
任意型別儲存void* ptrstd::any / std::variant
型別擦除void* + 函數指標std::function / 概念
C API 互操作void* context封裝於 RAII 類別內部