2011-03-14 69 views
4

我用傳統的C庫接口的工作(以C++),其公開不透明的指針作爲ç不透明指針陷阱

typedef void * OpaqueObject 

在圖書館:

OpaqueObject CreateObject() 
{ 
    return new OurCppLibrary::Object(); 
} 

當然,這絕對不提供爲該圖書館的客戶提供類型安全。應該從void指針改變typedef到結構指針的工作是完全一樣的,但提供少量的類型安全?

typedef struct OpaqueObjectInternal_ *OpaqueObject 
// OpaqueObjectInternal_ is NEVER defined anywhere in client or library code 

有沒有對齊的問題,或者我對現在擔心其他陷阱,我明確地指向一個結構,即使我真的不指向一個?

+3

在** C **中沒有叫'new'的操作符! – Mahesh 2011-03-14 21:16:28

+2

@Mahesh:我認爲OP是用C++封裝了一個C庫; 'new'發生在C++中(由'OurCppLibrary'限定符推斷出來的) – fbrereto 2011-03-14 21:19:59

+2

void *作爲一個不透明的對象是非常有意義的 - 你的事物的結尾不會弄亂對象,而且他們知道該怎麼做用它做。如果有的話,使其成爲'void *'使得它更安全,只要你像他們描述的那樣使用它的API。 – James 2011-03-14 21:40:08

回答

7

沒有疑難雜症;這種形式由於類型安全性而是首選。

不,對齊在這裏不是問題。指針本身具有已知的對齊方式,它將指向的對象的對齊只是庫實現而不是用戶關心的。

1

您建議的課程首先要考慮的是,您與其他人溝通的內容可能需要維護您正在編寫的代碼。除了所有其他事物之外,不透明對象是C方式向庫的用戶指示庫維護者完全不能保證對象的實現,而不是該對象可以與記錄的功能一起使用。通過刪除void *,你基本上向全世界宣佈,「我聲明這個曾經不透明的實現是穩定的。」這可能不是你想要的。其次,恕我直言,你提出的是一種讓人無法開心的半解決方案,更好的方法是開發一個包裝類。這還有一個額外的好處,就是允許你將不可避免地伴隨C風格不透明對象的init和destroy函數包裝在你的類的構造函數和析構函數中。這將允許您提供資源管理以及爲您的客戶提供安全類型,並完成更多的工作。

+1

我不明白爲什麼結構指針不透明。沒有定義客戶端可以訪問的結構(或者實現,就此而言)。關於包裝類,這是針對純粹的C消費者的。 – 2011-03-15 17:08:55

+0

看起來我很困惑這個例子使用C++構造和標題說的是C++,另外,我建議不要命名結構OpaqueObjectInternal_ Internal和尾部下劃線都是公共約定,它們表示私有實現。仔細閱讀註釋使我相信這個結構是內部實現而不是不透明指針。對我們來說這可能是一個教訓;-) – ltc 2011-03-16 06:51:53

+0

有人編輯了從C到C++的標題。你會命名結構? C接口知道每種類型都有不同的結構。 – 2011-03-16 21:48:09

2

實際上,一個C++類也是一個C結構。在圖書館

struct Object; 
struct Object* Object_Create(void); 

而且,C包裝這樣:所以,你可以簡單地這樣做

struct Object* Object_Create(void) 
{ 
    return new Object; 
} 

一個方法調用可能是這樣的:

uint32_t Object_DoSomething(struct Object* me, char * text) 
{ 
    return me->DoSomething(text); 
} 

我已經試過這我沒有看到任何缺點。