網站首頁 編程語言 正文
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-06-25 EF?Core的CRUD(增刪改查)基本操作_實用技巧
- 2022-07-21 Pandas常用數據結構
- 2023-07-16 uniapp 訂閱消息功能 授權彈框不彈或者點擊授權不發通知消息
- 2022-12-25 Flutter桌面開發windows插件開發_Android
- 2022-03-24 Android?TextView文本控件介紹_Android
- 2022-04-14 c語言的程序環境與預處理詳解_C 語言
- 2022-05-21 kubernetes?k8s入門定義一個Pod_云其它
- 2022-09-16 Numpy中的shape、reshape函數的區別_python
- 最近更新
-
- 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同步修改后的遠程分支