首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C/C++ 全域變數在標頭檔正確宣告與定義

     編輯:程式設計綜合問答

錯誤現象

在 changshu.h 直接定義全域變數:

// changshu.h
int g_count = 0; // 定義
double g_rate = 1.5;

多個 .cpp 包含此標頭檔,連結時出現 already defined in main.obj 錯誤。

原因

標頭檔被多個編譯單元包含,每個 .cpp 都會產生一份定義,連結器發現多重定義。

正確做法:宣告與定義分離

標頭檔(宣告)

// changshu.h
#ifndef CHANGSHU_H
#define CHANGSHU_H

extern int g_count;     // 宣告
extern double g_rate;   // 宣告

#endif

單一來源檔(定義)

// changshu.cpp
#include "changshu.h"

int g_count = 0;        // 定義(配置記憶體)
double g_rate = 1.5;    // 定義

其他來源檔使用

// other.cpp
#include "changshu.h"

void foo() {
    g_count++; // 正常使用
}

防止重複包含:Include Guard

#ifndef CHANGSHU_H / #define CHANGSHU_H / #endif 確保同一編譯單元內僅處理一次標頭檔內容,但**不解決多重定義問題**——定義仍須放在單一 .cpp。

C++17 inline 變數(現代替代方案)

若專案支援 C++17,可直接在標頭檔定義:

// changshu.h
inline int g_count = 0;
inline double g_rate = 1.5;

inline 指示連結器合併多重定義,適用於純標頭檔庫或簡化專案結構。

常見誤區

  • static 在標頭檔定義:每個編譯單元會有獨立副本,**非共享全域變數**。
  • 以為 Include Guard 能解決重複定義:它只防止同一 .cpp 重複編譯,跨 .cpp 仍各產生一份定義。

遵循「標頭檔宣告 extern,單一 .cpp 定義」原則,即可消除連結錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved