C++完成“隱蔽完成,開放接口”的計劃。本站提示廣大學習愛好者:(C++完成“隱蔽完成,開放接口”的計劃)文章只能為提供參考,不一定能成為您想要的結果。以下是C++完成“隱蔽完成,開放接口”的計劃正文
為何要有接口?
接口就是一個法式與其它法式交換的窗口。就好比有一個電視機,我其實不須要曉得它是如何任務的,我只需曉得按電源鍵便可以開啟電視,按節目加(+)減(-)可以切換電視頻道便可以了。
Java法式員都曉得Java中有interface可以完成對外的接口,但C++並沒有接口如許的語法,那它要好如何完成對外供給接口呢?我們可以經由過程純虛函數界說一個籠統類,專門用來聲明一個類的功效。
我們完成了一個法式模塊的開辟,要把這個法式模塊給他人用,你確定不會把源代碼給他(那他人就完整撐屋你的技巧了),你會把這個法式模塊編譯成一個庫(靜態庫lib或靜態庫dll)再給他人用。那他人拿到你的庫後如何用呢?這就須要看你的法式所供給的接口。C++的封裝性是特殊好的(小我認為比Java很多多少了,Java打成的jar包很輕易便可以被反編譯,C++要反編譯就艱苦多了),我只需給你編譯出的庫和接口的頭文件便可以了。
從一個實例講講完成計劃
須要
我們先來看一個場景。假定有一個電子文檔(Document)、一個文檔下有多個頁(Page),每一個頁下有多個文本單位(TextUnit,表現文檔內元素的根本單元),一個文檔中的一切文本單位對象都有獨一的ID。其類圖關系以下:
圖1 :類的關系圖
設計
依據需求,我們可以界說三個類Document、Page、TextUnit分離表現文檔、頁、文本單位,每一個類我們還須要一個對外的接口,因而須要三個對外的接口類IDocument、IPage、ITextUnit。
依據這些類我們先創立.cpp文件和.h文件,組織一下工程(EBook)目次構造以下:
圖2: 工程目次構造
這裡Document、Page、TextUnit就是詳細的完成類,IDocument、IPage、ITextUnit就是對外供給的接口,如許就完成了完成與接口分別。
代碼完成
IDocument.h: #pragma once class IPage; class IDocument { public: virtual ~IDocument(void){} public: //--------------------------------------------------------------- //function: // GenerateId 生本錢文檔內獨一的文本對象ID //Access: // virtual public //Parameter: //Returns: // int - 前往ID //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- virtual int GenerateId() = 0; //--------------------------------------------------------------- //function: // AddPage 添加一頁 //Access: // virtual public //Parameter: //Returns: // IPage* - 前往頁對象 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- virtual IPage* AddPage() = 0; }; IPage.h: #pragma once class ITextUnit; class IPage { public: virtual ~IPage(void){} public: //--------------------------------------------------------------- //function: // AddTextUnit 添加一個文本單位 //Access: // virtual public //Parameter: //Returns: // ITextUnit* - 文本單位對象 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- virtual ITextUnit* AddTextUnit() = 0; }; ITextUnit.h #pragma once class ITextUnit { public: ~ITextUnit(void){} public: //--------------------------------------------------------------- //function: // GetId 取得ID //Access: // virtual public //Parameter: //Returns: // int - 前往ID //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- virtual int GetId() = 0; //--------------------------------------------------------------- //function: // SetId 設置ID //Access: // virtual public //Parameter: // [in] int id - 要設置的ID //Returns: // void - //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- virtual void SetId(int id) = 0; };
供給C接口
從下面的代碼我們可以看到IPage可以由IDocument創立,ITextUnit可以由IPage創立。那成績來了,IDocument由誰來創立呢?這時候我們可以供給兩個全局的函數CreateDoc和DestroyDoc用來創立和燒毀IDocument的對象指針,這兩個函數是全局函數(C類型的函數),我們須要為其供給C的導出接口(這很主要)。其接口界說以下:
#pragma once #include "IDocument.h" #include "IPage.h" #include "ITextUnit.h" //=============================================================== //要導出靜態庫時,導出庫的工程和應用庫的工程都要加預編譯宏EXPORT_STATIC //要導出靜態庫時,導出庫的工程要加預編譯宏EXPORT_STATIC,應用庫的工程不消 //=============================================================== #ifdef EXPORT //導出庫 #define _API_ __declspec(dllexport) #else //導入庫 #define _API_ __declspec(dllimport) #endif //EXPORT #ifdef EXPORT_STATIC //導出靜態庫 #define EBAPI int #else //導出靜態庫 #define EBAPI extern "C" _API_ int #endif //EXPORT_STATIC //--------------------------------------------------------------- //function: // CreateDoc 創立Document對象 //Access: // public //Parameter: // [in] IDocument * & pDocument - //Returns: // EBAPI - //Remarks: // ... //author: luowf[/luoweifu] //--------------------------------------------------------------- EBAPI CreateDoc(IDocument*& pDocument); //--------------------------------------------------------------- //function: // DestroyDoc 燒毀一個Document對象 //Access: // public //Parameter: // [in] IDocument * pDocument - //Returns: // EBAPI - //Remarks: // ... //author: luowf[/luoweifu] //--------------------------------------------------------------- EBAPI DestroyDoc(IDocument* pDocument);
應用庫
我們可以將EBook編譯成一個靜態庫,然後再創立一個新的工程應用它。EBook工程設置:
創立一個新的工程UseEBook應用EBook庫。UseEBook工程配制:
Generation Properties\C++\Preprocess\Preprocess Definitions:EXPORT_STATIC
Generation Properties\Linker\General\Addtional Library Directories:lib庫地點途徑
Generation Properties\Linker\Input\Addtional Dependencies:EBook.lib
測試代碼:
#include "stdafx.h" #include <iostream> int _tmain(int argc, _TCHAR* argv[]) { IDocument* pDoc = NULL; if(CreateDoc(pDoc) != 0) { return -1; } IPage* pPage = pDoc->AddPage(); ITextUnit* pTextUnit = pPage->AddTextUnit(); std::cout << pTextUnit->GetId() << std::endl; DestroyDoc(pDoc); return 0; }
以上就是本文的全體內容,願望對年夜家的進修有所贊助。