網(wǎng)站首頁 編程語言 正文
前言
創(chuàng)建類來表示API
中的每個(gè)關(guān)鍵對象,同時(shí)提供這些類的方法
此處的API
風(fēng)格指的是如何表現(xiàn)API
的功能,以下4種:
- 純
C API
可以用C
編譯器編譯的API
。這種API
只包含一組自由函數(shù)以及輔助的數(shù)據(jù)結(jié)構(gòu)和常量。這種風(fēng)格的接口不包含對象或繼承,因此被稱為純C
模式
- 面向?qū)ο蟮?code>C++ API
這種風(fēng)格涉及對象(其中包含相關(guān)的數(shù)據(jù)與方法)的使用以及繼承、封裝和多態(tài)等概念的應(yīng)用
- 基于模板的
API
通過模板功能,C++
也支持泛型編程和元編程。它支持以泛型類型的方式編寫函數(shù)和數(shù)據(jù)結(jié)構(gòu),在以后使用時(shí),泛型類型可以通過具體類型來實(shí)例化,從而實(shí)現(xiàn)特化
- 數(shù)據(jù)驅(qū)動(dòng)型
API
這類接口的特點(diǎn)是,將參數(shù)通過靈活的數(shù)據(jù)結(jié)構(gòu)打包,連同命名的命令一起發(fā)送給處理程序,而不是調(diào)用特定的方法和自由函數(shù)
純C API
C
語言不支持對象封裝和繼承層次結(jié)構(gòu)等概念,因此,純C
語法的API
必須使用一組更為受限的語言特性來表示,比如typedef
、結(jié)構(gòu)體和全局命名空間中的函數(shù)調(diào)用等。因?yàn)?code>C語言中沒有namespace
關(guān)鍵字,要避免與其他C
庫中的名字發(fā)生沖突,對這種風(fēng)格的API
而言,所有公開的函數(shù)和數(shù)據(jù)結(jié)構(gòu)應(yīng)該使用一個(gè)公共的前綴
當(dāng)然,也可以使用內(nèi)部鏈接隱藏實(shí)現(xiàn)中的符號(hào)名,比如將符號(hào)名聲明為靜態(tài)的,這樣它們的作用域就限制在.c文件之中了。通過這種方式,可以確保任何這樣的函數(shù)都不會(huì)被導(dǎo)出到外部,從而不會(huì)導(dǎo)致符號(hào)沖突
// c++ 示例 class Stack { public: void Push(int val); int Pop(); bool IsEmpty() const; private: int *mStack; int mCurSize; }; // 純C API struct Stack { int *mStack; int mCurSize; }; void StackPush(struct Stack *stack, int val); int StackPop(struct Stack *stack); bool StackIsEmpty(const struct Stack *stack); // 進(jìn)一步改進(jìn) typedef struct Stack *StackPtr; void StackPush(StackPtr stack, int val); int StackPop(StackPtr stack); bool StackIsEmpty(const StackPtr stack); // 可以通過特定的API調(diào)用來完成數(shù)據(jù)庫結(jié)構(gòu)的創(chuàng)建與銷毀 StackPtr StackCreate(); void StackDestory(StackPtr stack);
在C API
的頭文件中使用extern "C"
限制,以便C++
程序能夠正確的編譯和鏈接C API
#ifdef _cplusplus extern "C" { #endif // C API聲明 #ifdef _cplusplus } #endif
面向?qū)ο蟮腃++ API
過程式編程、泛型編程、函數(shù)式編程
使用面向?qū)ο蟮?code>C++概念創(chuàng)建二進(jìn)制兼容的API
是極為困難的
基于模板的API
模板可以用來編寫在編譯時(shí)生成代碼或執(zhí)行代碼的程序(該技術(shù)稱為元編程)
模板可以在編譯時(shí)執(zhí)行一些工作,進(jìn)而改進(jìn)運(yùn)行時(shí)性能
#include <vector> template <typename T> class Stack { public: void Push(T val); T Pop(); bool IsEmpty() const; private: std::vector<T> mStack; }; // 可以定義一個(gè)typedef,這樣就可以更方便地使用該模板實(shí)例了 typedef Stack<int> IntStack; IntStack *stack = new IntStack();
模板實(shí)現(xiàn)方式的另一個(gè)選擇是,利用C
預(yù)處理器來定義一段文本,可以將其放入多個(gè)頭文件中
#include <vector> #define DECLARE_STACK(Prefix, T) \ class Prefix##Stack \ { \ public: \ void Push(T val); \ T Pop(); \ bool IsEmpty() const; \ private: \ std::vector<T> mStack; \ } DECLARE_STACK(Int, int);
模板提供了一種類型安全的在編譯時(shí)生成代碼的方式。你可以調(diào)試到類模板的時(shí)機(jī)代碼行中。除非你要編寫純C API
,無法使用模板,否則就應(yīng)該避免使用預(yù)處理器來模擬模板
模板的一個(gè)重要屬性是,不同于使用繼承時(shí)的動(dòng)態(tài)(運(yùn)行時(shí))多態(tài),它支持靜態(tài)(編譯時(shí))多態(tài)
不會(huì)像虛方法那樣存在運(yùn)行時(shí)代價(jià)
模板進(jìn)一步的益處,對于特定類型的實(shí)例類,可以特化它的某些方法
template <> void Stack<int>::Push(int val) { // 實(shí)現(xiàn)特定于int類型的壓棧功能 }
基于模板的API
的缺點(diǎn)
- 最嚴(yán)重的問題是:類模板的定義通常必須出現(xiàn)在公開的頭文件中
- 因?yàn)橐鼗0澹幾g器必須能夠訪問模板代碼的完整定義,顯而易見,這會(huì)暴露內(nèi)部細(xì)節(jié)
- 每當(dāng)其他文件包含了類模板定義所在的頭文件時(shí),內(nèi)聯(lián)的代碼都需要重新編譯,生成的代碼會(huì)被添加到每個(gè)使用該
API
的模塊的目標(biāo)文件。這會(huì)增加編譯時(shí)間,并致使代碼膨脹 - 實(shí)際上有些情況下你可以使用顯式實(shí)例化技術(shù)將模板的實(shí)現(xiàn)隱藏在
.cpp
文件中 - 模板的另一個(gè)缺點(diǎn)是,模板代碼中出現(xiàn)錯(cuò)誤時(shí),大多數(shù)編譯器生成的報(bào)錯(cuò)信息都是冗長且令人困惑的,可用
STLFilt
相對于運(yùn)行時(shí)開銷而言,代碼體積是需要優(yōu)先考慮的因素,那么應(yīng)該選擇面向?qū)ο蠓桨福悄0濉;蛘呦喾矗绻\(yùn)行時(shí)性能更為重要,那就應(yīng)該選擇模板
數(shù)據(jù)驅(qū)動(dòng)型API
數(shù)據(jù)驅(qū)動(dòng)型程序指的是:通過每次運(yùn)行時(shí)提供不同的輸入數(shù)據(jù),它可以執(zhí)行不同的操作
優(yōu)點(diǎn)
- 對于
API
將來可能發(fā)生的變化,它的容錯(cuò)性更強(qiáng) - 可以更容易地支持?jǐn)?shù)據(jù)驅(qū)動(dòng)型測試技術(shù)
p143
API
支持可變參數(shù)列表
- 聯(lián)合體
- 繼承
- void *
原文鏈接:https://blog.csdn.net/qq_29935433/article/details/126528731
相關(guān)推薦
- 2022-06-01 C語言超詳細(xì)講解字符串相乘_C 語言
- 2022-07-26 Android自定義評分控件的完整實(shí)例_Android
- 2022-10-02 Python實(shí)現(xiàn)遍歷讀取文件或文件夾_python
- 2022-03-27 C語言中scanf與scnaf_s函數(shù)詳解_C 語言
- 2022-05-05 利用Python編寫一個(gè)記憶翻牌游戲_python
- 2022-12-10 Android入門之TextClock的使用教程_Android
- 2022-03-16 linux下FastDFS搭建圖片服務(wù)器_Linux
- 2022-10-07 React中父組件如何獲取子組件的值或方法_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支