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;
}
以上就是本文的全體內容,願望對年夜家的進修有所贊助。