程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++完成“隱蔽完成,開放接口”的計劃

C++完成“隱蔽完成,開放接口”的計劃

編輯:關於C++

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;
}

以上就是本文的全體內容,願望對年夜家的進修有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved