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

C++ LNK2005 重複定義錯誤:將函式實作移至 .cpp 或標記 inline、使用 include guard 解決

     編輯:程式設計疑難解答

LNK2005 `已經在 xxx.obj 中定義` 通常是因為**函式/變數定義放在標頭檔(.h)**,且該標頭檔被多個 `.cpp` 包含,導致每個編譯單元都產生一份定義,連結時衝突。

你的代碼問題

標頭檔 `TimeAndDate.h` 內含 **完整的類別方法定義**(非 inline、非模板),例如:


inline void data_X::setX(int x) { ... } // inline 正確
void Time::display() { ... }            // 非 inline、非 static → 每個 .cpp 都會產生一份

解決方案(三選一)

1. 移至 .cpp(最標準)

  • `.h` 只保留類別宣告(方法原型)。
  • `.cpp` 包含 `.h` 並實作所有方法。

2. 標記 `inline`(適合短小函式)


inline void Time::display() { ... } // 加上 inline,編譯器會在每個調用點展開,不產生獨立符號

3. 模板化(若需泛型)

模板定義必須在 `.h`,編譯器實例化時處理重複。

標頭檔防禦

你已使用 `#ifndef MY_H_FILE ... #endif`,這防止**同一編譯單元重複包含**,但**無法防止跨編譯單元重複定義**。

建議重構


// TimeAndDate.h
#pragma once // 現代替代 include guard
#include 
#include 

class data_X { ... }; // 僅宣告
class Hour : public data_X { ... };
// ...
class Time {
public:
    Time(int, int, int);
    void display(); // 僅宣告
private:
    Hour hour;
    Minute minute;
    Second second;
};

// TimeAndDate.cpp
#include "TimeAndDate.h"
Time::Time(int h, int m, int s) : hour(h), minute(m), second(s) {}
void Time::display() {
    std::cout << std::setfill('0') << std::setw(2) << hour.getData() << ":"
              << minute.getData() << ":" << second.getData() << std::endl;
}

// main.cpp
#include "TimeAndDate.h"
int main() {
    Time t(20, 16, 13);
    t.display();
}

清理步驟

刪除 `Debug`/`Release`、`*.obj`、`*.pch` 等中間檔,或在 IDE 執行「清除方案」後重建,確保無舊物件檔殘留。

核心原則:**標頭檔只放宣告、內聯函式、模板;實作放 .cpp**,即可徹底避免 LNK2005。

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