日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

C/C++:多个.cpp文件包括同一个.h头文件定义方法

發布時間:2023/12/15 综合教程 21 生活家
生活随笔 收集整理的這篇文章主要介紹了 C/C++:多个.cpp文件包括同一个.h头文件定义方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文解決multiple definition of `XX'的錯誤?!境鲇诜磁老x的目的,你不是在http://blog.csdn.net/zhanh1218上看到的,肯定不是最新最全的?!?/p>

關于頭文件的定義中,請一定加上下面代碼(此為頭文件保護符):

<span style="font-size:14px;"><span style="font-size:12px;">#ifndef PERSON_H_
#define PERSON_H_
// 你的代碼塊
#endif /* PERSON_H_ */</span></span>

當中PERSON_H_為保護符的名字,一般建議與類名保持一致!樣例中我的類名為Person.h。

每當編譯器遇到#include時,都要去編譯相關代碼塊,可是編譯器不知道是不是已經編譯過了,假設編譯過了還去編譯,那是不是等于代碼塊寫了兩次呢?所以,須要有不反復編譯的機制,而這個機制正式以上代碼。

詳細實現為:#ifdef當且僅當變量已定義時為真,#ifndef當且僅當變量沒有定義時為真。一旦檢測結果為真,則運行興許操作直至遇到#endif。

也就是說:假設首次include "Person.h",PERSON_H_是未定義,此時,編譯器會define這個保護符,并運行代碼塊的編譯!直到遇到#endif。下次遇到這個保護符,就不會運行代碼塊的編譯了。這種機制保證了不會反復編譯。

實際使用中,我發現,單個cpp文件里多次include 同一個.h頭文件或者頭文件里多次include某個頭文件,不會有問題??墒?,多個cpp文件都include 同一個.h頭文件時,這樣會出問題。問題是類外定義的非static及非inline函數還是會報multiple
definition of `XX'的錯誤。【也就是說:#define的作用域僅僅是單個.cpp,而不是全局全部的.cpp文件】

終于解決方法是:僅僅在頭文件定義類的申明和類的主體定義(也就是{}內的內容),在一個同名的.cpp文件中定義類外函數的實現!問題完美解決。所以,就算是大神寫的書,書上也不全然是對的,或者表述的所有都清楚。

那么為什么頭文件能夠定義成下面形式呢?而不是僅僅申明,不定義類體呢?

<span style="font-size:14px;"><span style="font-size:12px;">class A
{
// 類定義
};</span></span>

類的定義,僅僅是告訴編譯器,類的數據格式是怎樣的,實例話后對象該占多大空間。類的定義也不產生目標代碼。因此它和普通變量的聲明唯一的差別是不能在同一編譯單元內出現多次。

還有一個原因就是,類能夠在多個.cpp文件中重定義,變量卻不行,除非用extern或者staic修飾的變量。

至于普通變量:同意static型的變量的定義;同意extern申明(不能定義!);直接申明比如int
a; 是不行的,也是多次又一次定義。

extern表明該變量在別的地方已經定義過了,在這里要使用那個變量;static 表示靜態的變量,分配內存的時候,存儲在靜態區,不存儲在棧上面?!疽黄诲e的Blog:點擊打開鏈接】

以下是代碼演示樣例,此實例部分為C++ Primer練習題。【反爬蟲,第二天更新代碼!】

/*********************************************************************
 * file_name: vector_test.cpp
 *
 *    Created on: 2014年6月28日 下午3:34:23
 *        Author: The_Third_Wave, Blog: http://blog.csdn.net/zhanh1218
 *         Email: zhanh121823@sina.com
 * Last modified: 2014年6月28日 下午3:34:23
 *********************************************************************/

#include <iostream>
#include <vector>
#include <string>
#include "Headers/Person.h"

extern int k;
int main()
{
	std::vector<Person> per = {{"The_Third_Wave", 100, "Blog: http://blog.csdn.net/zhanh1218"}}; // 類初始化+vector初始化,所以{{}, {}}必須的
	for (auto &p: per)
	{
		print(std::cout, p);
	}
}
/*********************************************************************
 * file_name: ddqdq.cpp
 *
 *    Created on: 2014年6月28日 下午10:28:42
 *        Author: The_Third_Wave, Blog: http://blog.csdn.net/zhanh1218
 *         Email: zhanh121823@sina.com
 * Last modified: 2014年6月28日 下午10:28:42
 *********************************************************************/
#include <iostream>
#include <vector>
#include "Headers/Person.h"

extern int k;
/*********************************************************************
 * file_name: Person.h
 *
 *    Created on: 2014年6月28日 下午11:47:08
 *        Author: The_Third_Wave, Blog: http://blog.csdn.net/zhanh1218
 *         Email: zhanh121823@sina.com
 * Last modified: 2014年6月28日 下午11:47:08
 *********************************************************************/

#ifndef PERSON_H_
#define PERSON_H_
/*****************************BEGIN***********************************/
#include <iostream>
#include <string>
using namespace std;
extern int a;
class Person
{
    friend istream &read(istream &is, Person &item);
    friend ostream &print(ostream &os, const Person &item);
public:

    Person() = default;
    Person(const string &n, unsigned int a, string add):
	    name(n), age(a), address(add) { }
    Person(istream &);

    string Name() const {return name;}
    unsigned int Age() const {return age;}
    string Address() const {return address;}

private:
    string name = "";
    unsigned int age = 1;
    string address = "";
};

inline
Person::Person(istream &is)
{
    read(is, *this);
}
/******************************END************************************/
#endif /* PERSON_H_ */
/*********************************************************************
 * file_name: Person.cpp
 *
 *    Created on: 2014年6月28日 下午10:55:32
 *        Author: The_Third_Wave, Blog: http://blog.csdn.net/zhanh1218
 *         Email: zhanh121823@sina.com
 * Last modified: 2014年6月28日 下午10:55:32
 *********************************************************************/
#include <iostream>
#include <string>
#include "Person.h"
using namespace std;

istream &read(istream &is, Person &item)
{
    is >> item.name >> item.age >> item.address;
    return is;
}
ostream &print(ostream &os, const Person &item)
{
    os << item.name << " " << item.age << " " << item.address << endl;
    return os;
}

還有不懂的請留言。

本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原創。還有未涉及的,會不定期更新,有錯誤請指正。

假設你看到這篇博文時發現不完整,那是我為防止爬蟲先公布一半的原因,請看原作者Blog。

假設這篇博文對您有幫助,為了好的網絡環境,不建議轉載,建議收藏!假設您一定要轉載,請帶上后綴和本文地址。

總結

以上是生活随笔為你收集整理的C/C++:多个.cpp文件包括同一个.h头文件定义方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。