網站首頁 編程語言 正文
C++頭文件定義全局函數或類成員函數
你可能很熟悉C/C++的聲明定義規則:
頭文件中聲明變量和函數,源文件中定義變量和函數。在頭文件中定義變量和函數會導致“重定義”,
因為包含該頭文件的不同元文件將創建變量或函數的多個副本,這些副本都具有"extern”的可見性,
必然會造成沖突。
上述認知在你第一次接觸到模板類時受到了沖擊:模板類的實現都在頭文件內。
接著你還接觸到了所謂的"HeaderOnly"庫,他們只包含頭文件,沒有源文件。
為什么定義可以都寫在頭文件里而沒有造成“重定義”錯誤呢?在講清楚這個問題之前,你需要回顧下
line關鍵字。
line修飾的函數稱為內聯函數,他告訴編譯器允許將函數在調用位置展開,而不使用函數調用。優點是
可以減少函數調用的開銷,副作用是會導致代碼體積增加,因為每個調用位置都會復制一遍。
事實上,現代編譯器已經十分智能,他會自動選擇是否需要將函數內聯,即使你沒有用inline修飾。反之,
即使用了inline,編譯器也不一定會內聯。既然這樣,inline關鍵字似乎可以刪掉了,之所以還保留到現在,
是因為他的附加特性“允許存在多個副本”還有用。
inline修飾的函數可以存在多個副本,所以你可以在頭文件中用inline定義一個全局函數,然后在多個源文件
中調用而不用擔心造成“重定義”錯誤,編譯器會保證他們都使用同一個定義(相同的函數地址)。甚至這些
定義可以有不同的實現,不過這屬于未定義行為,編譯器可能隨即選擇一個。
所以現在的inline關鍵字實際上起到的是類似multiple的作用。
C++中,類聲明中直接定義的成員函數,都被當從inline函數,所以不會造成“重定義”,這解釋了文章開頭的
問題。模板有一點不同,但有一點類似。模板由于存在不同的模板參數,天然存在多個不同定義,所以編譯器
負責自動選擇合適的定義,并不會認為是“重定義”。
現在,你也可以寫一個HeaderOnly的庫了:
- 使用inline修飾全局函數。
- 使用類成員函數。
- 使用模板。
原文鏈接:https://blog.csdn.net/skysky97/article/details/126307636
相關推薦
- 2022-03-15 antd-mobile 請求時Loading組件
- 2022-11-10 利用C++實現獲取文件夾下所有文件名_C 語言
- 2022-12-24 Go高效率開發Web參數校驗三種方式實例_Golang
- 2022-07-09 python沒有gpu,如何改用cpu跑代碼_python
- 2023-07-09 時間模式更改為:“剛剛“,“分鐘前“,“小時前“
- 2022-05-23 詳解Rust中的workspace_相關技巧
- 2022-12-23 Kubernetes有狀態應用管理StatefulSet使用詳解_云其它
- 2021-12-02 C++內存分布及用法_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支