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

C++ 連結錯誤 LNK2005/LNK1169:頭文件定義變數導致多重定義

     編輯:程式設計疑難解答

錯誤重現

// a.h
int 大小 = 0;  // 直接在頭文件定義變數

// a.cpp
#include "a.h"
void _tmain() { 大小 = 48; }

// b.cpp
#include "a.h"
void abc() { 大小 = 48; }

編譯時產生:

error LNK2005: "int 大小" (?大小@@3HA) 已經在 b.obj 中定義
error LNK1169: 找到一個或多個多重定義的符號

原因分析

頭文件被多個 .cpp 包含時,int 大小 = 0; 會在每個編譯單元(Translation Unit)中產生一個**定義**。連結器發現同一個符號在多個 .obj 中都有定義,因而報錯。#pragma once 或 #ifndef 僅能防止同一編譯單元內重複包含,無法跨編譯單元解決重複定義。

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

頭文件(a.h)僅宣告

// a.h
#pragma once
extern int 大小;  // 告訴編譯器:這個變數在別處定義,型別為 int

僅一個 .cpp 進行定義

// a.cpp
#include "a.h"
int 大小 = 0;  // 真正分配記憶體、初始化

void _tmain() { 大小 = 48; }

其他 .cpp 正常包含頭文件使用

// b.cpp
#include "a.h"
void abc() { 大小 = 48; }  // 連結時會解析到 a.cpp 的定義

進階:C++17 inline 變數(單一定義規則例外)

若使用 C++17,可在頭文件直接定義:

// a.h (C++17)
#pragma once
inline int 大小 = 0;  // 允許在多個編譯單元出現,連結器會合併

但傳統專案建議採用 extern + 單一定義檔,相容性最佳。

常見誤區

  • const 變數:C++ 中 const int x = 10; 在頭文件預設具有內部連結,每個 .cpp 會有獨立副本,**不會**造成 LNK2005。但若加上 extern const int x; 則需單一定義。
  • static 變數:同理,內部連結,各編譯單元獨立副本。
  • 函式定義:非 inline 函式定義在頭文件同樣會造成多重定義錯誤。

總結

頭文件僅放 宣告,實際 定義 放在單一 .cpp。使用 extern 關鍵字明確區分,即可徹底解決 LNK2005/LNK1169。

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