簡體   English   中英

在C中模擬訪問說明符

[英]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.cfoo.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM