1. 程式人生 > >C++ header file And Source file

C++ header file And Source file

C++ 的專案一旦過大,對檔案的複用,整理等操作有了嚴格的要求.前一段時間就為自定義標頭檔案的引入頭疼了好久,現在說說我填過的坑.

一.標頭檔案,原始檔的概念,關係這裡不贅述了,網上的部落格太多了,並且都比較詳細.

這裡給個文章地址:http://www.cplusplus.com/forum/articles/10627/

二.遇到的問題

1.檔案引用無誤但....

        [email protected]:~/Desktop/temp$ g++ main.cpp -o a

  /tmp/ccTqCUgO.o:在函式‘main’中:
  main.cpp:(.text+0x1f):對‘MyClass::foo()’未定義的引用

  collect2: error: ld returned 1 exit status

神馬? 沒定義?


定義了啊!為什麼不能...

三.建議

寫專案一定要嚴謹,不要混淆各個檔案

.h(還有.hpp等)檔案是標頭檔案,只寫變數,函式,模板,類的宣告.

.c(.cpp,.cc等)檔案寫標頭檔案中宣告的檔案的定義,每一個模組寫一個檔案不要相互混淆

對於標頭檔案中有模板類的情況,建議講類的函式定義寫在標頭檔案中,因為有時會報錯

四.填坑

現在說說我遇到的問題的解決,

首先建立標頭檔案

//a.h

#ifndef _A_H_ //這個是標頭檔案的巨集,只要滿足變數的命名規則就行

#define _A_H_

//函式的宣告

void show();

#endif

//a.cpp

#include "a.h"

#include <iostream>

void show(){

    std::cout << "引用成功"<<endl;

}

//main.cpp

#include "a.h"

int main(){

    show();

    return 0;

}

整個檔案的編寫,引入都沒有問題,那為什麼會報錯呢?讓我來告訴你,

1.a.h檔案寫的是函式的宣告

2.a.cpp檔案寫的函式的定義,此處在檔案中引入了a.h,#include"XX"的意思就是把檔案的內容替換#include

3.直接在main檔案中引入了a.h,如果按照#include只是把檔案的內容替換掉的話,好像main.cpp中只有show函式的宣告,和show函式的呼叫.這不就又錯了嘛!實則不然,在c++的編譯器編譯時,壓根不管各個檔案的相互關係,只在乎當前檔案有沒有我要的資訊,在mian.cpp中檔案的宣告有,則編譯可以通過.在C++編譯時,有兩個同名檔案(字尾不同),a.h與a.cpp,其實名字可以不同,一般建議名字一致.在編譯時,編譯器會自動查詢整個工程檔案中有沒有對標頭檔案中的函式的定義,有則引用,沒有就報錯,不會在乎檔案的位置和名字,前提要在同一工程目錄下,且檔案的引入路徑正確.也就是說.在編譯時,main函式呼叫的函式在標頭檔案中宣告就行,而檔案的定義只要在同一工程下的檔案中有定義即可,並且不用引入到呼叫處.切記:

在標頭檔案中寫函式的定義也可以成功編譯,引入定義函式的cpp檔案後也可以編譯,(因為兩個檔案與.txt檔案沒有區別)但是不要將CPP檔案引入,可能會造成函式的多次定義而報錯,況且標頭檔案也有重複引入的危險(所以用#ifndef  #define ...#endif取消重複引入).

4.之後所以報錯的原因是沒有全部編譯,整個專案包含多個頭檔案和原始檔,編譯器在編譯時是分別編譯各個cPP檔案的,不會編譯標頭檔案,因為也沒有用.在執行時從main函式開始.而我報錯的原因就是隻編譯的main.cpp而沒有編譯所有相關的cPP檔案,所以報錯.(注:檔案的編譯是分別編譯,然後連結,而程式執行是從mian 函式開始,所以不要只編譯含mian 函式的檔案)

5.所以編譯整個工檔案就可以使檔案正常執行


注:模板的宣告與實現不能分開寫,必須寫在同一檔案中(但是我在測試時可以分別寫,但是不建議)

https://www.zhihu.com/question/20630104

相關推薦

C++ header file And Source file

C++ 的專案一旦過大,對檔案的複用,整理等操作有了嚴格的要求.前一段時間就為自定義標頭檔案的引入頭疼了好久,現在說說我填過的坑.一.標頭檔案,原始檔的概念,關係這裡不贅述了,網上的部落格太多了,並且都比較詳細.這裡給個文章地址:http://www.cplusplus.co

C語言VS編譯環境中的resource file and source file的區別

Sourcefile資料夾裡面放的是CPP檔案這些 Resourcefile資料夾是資原始檔夾,裡面可以放你程式裡需要的資源,包括圖示,對話方塊,圖片等等; 對應的檔案如下: Source Files - *.c,  *.cpp Header Files - *.h Re

C++:cannot open source file問題

最近,在一些專案中只要引用了標準C++程式碼的地方,都會報cannot open source file這樣的錯誤,比如: 查詢問題後發現,是由於Configuration Properties -> VC++ Directories -> Include Directorie

IO Redirection in C++ (redirect cin/cout to file stream, and restore)

Author: YuMaNzI 2014/01/19 #include<iostream>#include<fstream>#include<string>void f(){ std::string line;while(st

c++ store vector in file and reverse

解決方法: #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost

C# SharpSsh Private-public a pair key to Upload and Download File

先說說背景 公司要我做一個小的Console應用程式,完成每天的檔案上傳。要上傳的伺服器是第三方Linux系統,用的是SSH,公鑰祕鑰配對的方式。 問題步驟 1.生成公鑰私鑰,將公鑰發給要上傳到的第三方伺服器 2.用Tamir.SharpSsh 完成上傳(StackOve

WCF: Generate Proxy Class and Configuration file for Client

alt host man class studio generated wcf div intro 1. please keep WCF service running 2. and two ways to achive this   a. add Service R

class file editor source not found 解決Eclipse打開.class文件

.cn ins ips tar 文件路徑 .net exe com 文件類型 1.準備材料 jad.exe 下載地址 https://varaneckas.com/jad/,根據系統去選擇(就當是廢話) 下載下來的是jad158g.win.zip壓縮文件,解

tar(child):bzip2:Cannot exec: No such file and directory

bzip2 下午從阿裏雲拷貝一個比較大的壓縮包到另外一臺阿裏雲主機,使用scp發現拷貝速度有點慢,想起以前用過pv+lz+tar的方法傳輸Linux下的大數據,二話不說,開始幹。因為是翻墻下載的包,一開始以為是自己下載的安裝包有問題,但仔細看了下提示“bzip2:Cannot exec...”,想了下,

【Vue報錯】Module build failed: Error: No parser and no file path given, couldn't infer a p arser.

3.0 OS could modules exp ports -- hot loader 在創建一個vue項目啟動時報錯,報錯的內容為: error in ./src/App.vue Module build failed: Error: No parser and no

【轉載】What is the difference between authorized_keys and known_hosts file for SSH?

led accounts dep protocol wide HERE data round enc The known_hosts file lets the client authenticate the server, to check that it isn‘t c

c語言 05-樹8 File Transfer

05-樹8 File Transfer We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer

自定義idea File and Code Templates

1.給class新增作者,描述,建立時間 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") /** *@author

samba服務錯誤:Starting SMB/CIFS File and Active Directory Server. [FAIL]

出現錯誤:Starting SMB/CIFS File and Active Directory Server. [FAIL] 現象:samba服務兩次啟動,其中有一次沒有起來顯示fail 方案一: sudo rm /etc/init/samba-ad-dc.conf

C/C++檔案操作效率比較——FILE/fstream

【背景】利用GetTickTount函式進行效率測試,對比C/C++在讀寫文字檔案和二進位制檔案時耗時大小 【裝置】電腦配置如下:(CPU四核八執行緒) 程式碼如下: #include <iostream> #include <fstream> #include

c# 後臺post,包含file檔案

http request 相關 private bool Upload(KeyValuePair<string, string>[] paramString,Stream paramFileStream) { var actionUr

Idea使用筆記——自定註釋模板&自定義程式碼模板&自定義File and Code Templates

設定類註釋: File-->settings-->Editor-->File and Code Templates-->Files 類註釋模板: /** * @Classname ${NAME} * @Description TODO * @autho

android Please fix the module's configuration in the build.gradle file and sync the project again

新匯入了 安卓專案就出現了這個問題。而且發現 專案 就是出現了一個 專案名, 不能開啟 專案明細裡面的東西看,也是奇怪 試著編譯 一下 gradle 專案,看看是不是會出現其他更多提示錯誤的。 結果發現是 因為    classpath 'com.android.tools

android Please fix the module's configuration in the build.gradle file and sync the project again

新匯入了 安卓專案就出現了這個問題。而且發現 專案 就是出現了一個 專案名, 不能開啟 專案明細裡面的東西看,也是奇怪 試著編譯 一下 gradle 專案,看看是不是會出現其他更多提示錯誤的。 結果發現是 因為    classpath 'com.andro

每次建立keil工程的時候都會彈出提示: Copy STANDARD 8051 startup code to project folder and add file to project

很多初學者在使用keil軟體建立工程的時候,在選擇好微控制器之後會彈出來一個視窗,詢問是否要複製啟動程式(startup)。這時候,大家就開始糾結到底是要選擇是還是選擇否呢? 1,首先先解釋一下這個啟動程式是什麼意思: 在執行c程式碼之前都要先執行一個彙編程式,