在 C 中模拟访问说明符

Ban*_*oot 5 c c++ oop

是否可以在 C 中模拟 C++ 访问说明符 [public、private、protected]?更一般地说,C++ 编译器如何确保类的私有成员不被非成员函数访问?

Ern*_*ill 5

C++ 访问控制完全是编译器的想象:你不能访问私有成员,只是因为编译器会拒绝编译任何试图这样做的代码。

通过欺骗编译器认为指向实例的ClassWithPrivateMember指针实际上是指向实例的指针来访问 C++ 类的私有成员实际上相当简单ClassWithPublicMember——即,通过使用稍微修改的头文件,您通常可以得到访问你不应该访问的东西。并不是说有人做过这样的事情......

在 C 中进行访问控制的最佳方法是传递指向不透明类型的指针: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;
}
Run Code Online (Sandbox Code Playgroud)

现在,您分发foo.c编译成一个库,以及foo.h. foo.h以类型的公共接口形式声明的函数,但该类型的内部结构是不透明的;实际上,调用的客户端create_foo()无法访问foo对象的私有成员。

我们的朋友 theFILE*是类似的东西,除了类型FILE通常不是真正不透明的。只是大多数人(明智地)不会去探索它的内脏。在那里,访问控制仅通过默默无闻来实施。

  • 看,这正是不透明类型的用途,因为 void * 没有给出关于正在发生的事情的语义线索: typedef struct thing thing_t; 并且您有一个类型,上面写着“内部没有用户可维修的部件”,同时仍然提供有关该类型应该做什么的信息。 (2认同)