[英]Emulate access specifiers in C
是否可以在C中模擬C ++訪問說明符[public,private,protected]? 更一般地說,C ++編譯器如何確保非成員函數不能訪問類的私有成員?
C ++訪問控制完全是編譯器想象的一個例子:你不能只訪問私有成員,因為編譯器會拒絕編譯任何試圖這樣做的代碼。
通過欺騙編譯器認為指向ClassWithPrivateMember
實例的指針實際上是指向ClassWithPublicMember
實例的ClassWithPublicMember
- 即通過使用略微修改的頭文件,您可以訪問C ++類的私有成員實際上非常簡單通常可以訪問您不應該訪問的內容。 並不是說有人做過這樣的事......
在C中進行訪問控制的最佳方法是將指針傳遞給opaque類型: struct
對象,其定義不適用於客戶端代碼。 如果你提供一個foo* create_foo()
方法和一系列的操作方法foo*
,隱藏的實際定義foo
從客戶端,那么你就必須取得類似的效果。
// File "foo_private.h"
struct foo {
int private1;
char private2;
};
// File "foo.h"
typedef struct foo foo;
foo * create_foo(int x, char y);
int mangle_foo(foo *);
// file "foo.c"
#include <stdlib.h>
#include "foo.h"
#include "foo_private.h"
foo * create_foo(int x, char y) {
foo * f = (foo *) calloc(1, sizeof(foo));
f->private1 = x;
f->private2 = y;
}
int mangle_foo(foo *f) {
return f->private1 + f->private2;
}
現在,您將foo.c
與foo.h
一起分發到庫中。 在foo.h
聲明的函數形成一個類型的公共接口,但該類型的內部結構是不透明的; 實際上,調用create_foo()
的客戶端無法訪問foo
對象的私有成員。
我們的朋友FILE*
是類似的東西,除了FILE
類型通常不是真正不透明的。 只是大多數人(明智地)不會去探索它的內臟。 在那里,訪問控制僅通過默默無聞來實施。
我建議強烈反對使用另一個答案中建議的void *指針,這會拋棄所有類型安全。 你可以改為向前聲明struct foo;
在沒有指定內容的頭文件中,您可以將這些結構和指針傳入和傳出頭部中聲明的接口函數。 struct實現隱藏在該單元的.c文件中。
如果要保留在結構和其他類型(例如int)之間進行更改的選項,可以在標頭中使用typedef
來包裝接口的類型。
您可以使用的其他技術包括在.c文件static
內聲明函數,以便它們不能與其他源鏈接,即使這些其他源聲明了該函數。
有很多方法可以達到目標,以下是我的:
該示例包括類“struct test_t”和類函數“test_create”以及成員函數“print”
test.h:
struct test_t {
// Member functions
void (*print)(struct test_t *thiz);
// Private attributes
char priv[0];
};
// Class functions
struct test_t *test_create(int number);
test.c的:
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
// priv attr
struct test_priv_t {
int number;
};
// member functions
static void print(struct test_t *thiz)
{
struct test_priv_t *priv = (struct test_priv_t*)thiz->priv;
printf("number = %d\n", priv->number);
}
// Class functions
struct test_t *test_create(int number)
{
struct test_t *test = (struct test_t *)malloc(sizeof(struct test_t) + sizeof(struct test_priv_t));
// setup member function
test->print = print;
// initialize some priv attr
struct test_priv_t *priv = (struct test_priv_t*)test->priv;
priv->number = number;
return test;
}
main.c中:
#include "test.h"
int main()
{
struct test_t *test = test_create(10);
test->print(test);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.