2013-02-26 151 views
5

它可以模擬命名空間用C這樣的:命名空間與結構

#include <stdio.h> 
#include <math.h> 

struct math_namespace { 
    double (*sin)(double); 
}; 
const struct math_namespace math = {sin}; 

int main() {  
    printf("%f\n", math.sin(3)); 

    return 0; 
} 

有什麼缺點這一點,或只是其中一個前綴更有意義的情況呢?這樣做似乎更清潔。

+0

'sin'有'double sin(double)'類型,你應該改變類型或使用'sinf'。 – 2013-02-26 17:00:11

+0

有趣的方法。但我認爲這與前綴的可讀性一樣有害。我看到的主要缺點是,如果函數指針未初始化,而不是鏈接錯誤,則會出現運行時錯誤。 – StoryTeller 2013-02-26 17:02:37

+1

它引入了更多的間接性,還是不是? (有時間罰分?) – qPCR4vir 2013-02-26 17:05:45

回答

3

該方法已用於Jacob Navia等實際項目中,例如C Containers Library。 C不適用於面向對象的編程。這不是很有效,因爲你必須(1)訪問結構和(2)取消引用函數指針。如果你真的想要前綴,我認爲改變你的標識符仍然是最好的解決方案。

0

爲什麼要重新發明輪子?一個缺點是所有的設置都可能不同步,並且還需要添加到命名空間中,以便更改結構。

並沒有'使用命名空間',所以你總是要指定它。什麼和不同參數類型的功能?

+0

哎呀!糾正了這一點。 – QuentinUK 2013-02-26 17:06:29

+1

什麼*關於*具有不同參數類型的功能? – StoryTeller 2013-02-26 17:08:30

+0

重新發明輪子是什麼意思?由於項目需求,使用C++不是一種選擇。 – Overv 2013-02-26 17:12:40

0

那麼,這確實允許你導出你的命名空間,它確實允許客戶端模塊使用的東西是名爲sin靜態或本地版本。所以,從這個意義上說,它確實有效。

不利的一面是,它不是非常適合ELF的。結構初始化被隱藏在可寫數據頁面的中間,並且需要修補它。除非你是靜態鏈接,否則這是一個加載時間修正。在光明的一面,它只是複製ELF調度表所做的事情,所以我敢打賭它甚至不會更慢。在Windows上,我認爲這些考慮是相似的。

1

我已經使用了這種風格一段時間了。它有助於組織程序,而不用使用OOP語言的過多行李。沒有性能損失,因爲在C中訪問函數指針與直接訪問函數相同。我喜歡它,我甚至寫了一篇非常簡短的文章。可以在頁面底部的「C with Structs」鏈接下的http://slkpg.1eko.com找到它。 直接鏈接是http://slkpg.1eko.com/cstructs.html