1

例如,

Class Test {
        private:
            int x;
        public:
            int y;
}obj;

现在,可以访问 obj.y 但不能访问 obj.x

我的问题是编译器如何限制对私有数据的访问?

此外,如何在 C 结构中实现访问说明符?

4

2 回答 2

9

编译器拥有翻译单元中所有代码的所有信息(源文件和所有包含的头文件),因此可以跟踪哪些成员是私有的,哪些不是。编译器如何做无关紧要,不同的编译器可以以不同的方式实现它。

私有/公共成员是一个纯粹的编译时概念,编译的可执行代码中没有任何东西可以强制执行它。

于 2013-09-27T11:16:04.723 回答
1

我的问题是编译器如何限制对私有数据的访问?

当源代码引用任何变量时,C++ 编译器必须进行名称查找以查找变量(它可以是局部变量、成员变量、全局变量等),并且必须进行访问检查。编译器拥有关于类型、变量和范围的所有信息,因此当源代码引用一个变量时,编译器知道该变量是否可访问。如果变量不可访问,编译器会拒绝源代码。

问“如何”并没有真正的明智答案——它是编译器,它就是这样做的。如果您尝试编写 C 代码来做同样的事情,知道它是如何工作的对您没有帮助,因为您可以在程序的源代码中做的事情与编译器所做的事情完全不同。这就像问飞机如何飞行,然后问你如何在汽车中飞行。知道一个的答案与另一个无关。

此外,如何在 C 结构中实现访问说明符?

两种选择:

  1. C 不支持,使用 C++

  2. 将 a 存储void*在指向某些不透明类型的结构中,并且只有“私有”函数(即 API 内部)知道该不透明类型的详细信息。

这是一个简单的例子

//
// in header only "public" data is visible
//

struct Data {
    int some_number;
    void* private_data;
};

Data* create_Data(int i, int j);
void manipulate_Data(Data*);

//
// in source file, these functions know what the `void*` points to and can use it
//

struct InternalData {
    int another_number;
};

InternalData* get_internals(Data* d)
{
    return (InternalData*)d->private_data;
}

Data* create_Data(int i, int j)
{
    Data* data = (Data*)malloc(sizeof(Data));
    data->some_number = i;
    InternalData* internal = (InternalData*)malloc(sizeof(InternalData));
    internal->another_number = j;
    data->private_data = internal;
}

void manipulate_Data(Data* d)
{
    data->some_number += get_internals(d)->another_number;
}
于 2013-09-27T11:40:54.330 回答