修復 C++ 中一個函式的多重定義錯誤

Muhammad Husnain 2023年10月12日
修復 C++ 中一個函式的多重定義錯誤

這篇文章是關於 C++ 中經常出現的錯誤的解決方法,即函式的多個定義

修復 C++ 中的 multiple definitions of a function 錯誤

這種錯誤通常是在我們試圖分離函式原型和它的定義時引起的。因此,建議你將原型和定義分開放在不同的檔案中,並相應地包含該檔案。

參考下面的例子來理解這個問題。

示例程式碼(file1.cpp):

// file1.cpp
#include <iostream>
using namespace std;

class classB {
  friend void f1();

 public:
  classB(int i = 1, int j = 2) : a(i), b(j) {
    cout << "Hello from constructor\n";
  }

 private:
  int a;
  int b;
  void printfun() { cout << "a=" << a << endl << "b=" << b << endl; }
};
void f1() {  // ERROR HERE
  cout << "f1 start" << endl;
  classB tmp(3, 5);
  tmp.printfun();
  cout << "f1 end" << endl;
}

示例程式碼(main.cpp):

// main.cpp
#include <iostream>

#include "file1.cpp"
using namespace std;

int main() {
  cout << "calling function" << endl;
  f1();
  cout << "exit from main" << endl;
  return 0;
}

這就是在你的情況下發生的事情。由於 file1.cpp 檔案中的 #includefile1.cppmain.cpp 都包含 f1() 的定義,並且連結器不知道在你的檔案中使用哪一個程式並抱怨它。

解決方案是從 main.cpp 中刪除包含 f1() 定義的 CPP 檔案,並在單獨的標頭檔案中包含 f1() 的宣告,並將其包含在 main.cpp 中。編譯器將處理 f1() 的宣告,而連結器將僅依賴 file1.cpp 中的 f1() 定義。

示例程式碼(file1.h):

// file1.h
#include <iostream>

class classB {
  friend void f1();

 public:
  classB(int i = 1, int j = 2) : a(i), b(j) {
    std::cout << "Hello from constructor\n";
  }

 private:
  int a;
  int b;
  void printfun() { std::cout << "a=" << a << endl << "b=" << b << std::endl; }
};

示例程式碼(file1.cpp):

// file1.cpp
#include "file1.h"
using namespace std;
void f1() {
  cout << "f1 start" << endl;
  classB tmp(5, 6);
  tmp.printfun();
  cout << "f1 end" << endl;
}

示例程式碼(main.cpp):

// main.cpp
#include <iostream>

#include "file1.h"
using namespace std;

int main() {
  cout << "calling function" << endl;
  f1();
  cout << "exit from main" << endl;
  return 0;
}

讓我們從標頭檔案 file1.h 開始。標頭檔案包含所有內容的定義,如函式定義、任何結構或類定義或任何常量定義。

這個 .h 副檔名告訴編譯器不要編譯這個檔案。它就像一個文字檔案,任何人都可以閱讀。

這意味著標頭檔案是一個文件檔案。如果以後有程式設計師想使用某些函式,只需要檢查函式的原型,不需要詳細介紹函式定義。

最後,模板程式碼也應該在標頭檔案中。

CPP 檔案現在定義了在標頭檔案中宣告的函式。這告訴編譯器該檔案將被編譯並轉換為二進位制檔案。

你的程式碼的完整性將受到保護,未經你的許可,任何人都不能修改它。這意味著這種程式碼分離也確保了程式碼檔案的安全性。

這種技術背後的另一個原因是便攜性。例如,你編寫了一個二進位制搜尋程式碼,以後可以在許多其他程式中使用。

如果你有這些單獨的函式檔案,則可以在任何其他專案中輕鬆使用這些函式。

最後,主檔案只包含主函式,並在頂部包含標頭檔案。這個檔案只包含主函式,它只呼叫所有函式,沒有別的。

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn

相關文章 - C++ Error