9

现在我一直在学习内联函数,我遇到了一些让我很困惑的事情

看这堂课

class Nebla{
private:
    int x;
public:
    inline void set(int y){x=y;}
    inline void print(){cout<<x<<endl;}
};

它有一个私有数据成员:int x;

它有两个公共的内联函数:set(int y)print()

现在,由于这两个函数是内联的,所以当它们被调用时,编译器会将函数调用替换为函数的内容。

所以如果我这样做

Nebla n;
n.set(1);
n.print();

由于这两个函数是内联的,它应该是等价的:

Nebla n;
n.x=1;
cout<<n.x<<endl;

但等一下,x是私人的。因此,这不应该工作。

但它确实如此,我很困惑为什么它确实有效,尽管通常你不能从课堂外访问私人成员?

谁能解释一下为什么您可以从类外部访问私有数据成员,但是当成员函数是内联的时,尽管内联只是将函数调用替换为函数的内容,但它可以吗?

4

4 回答 4

11

数据成员保护纯粹是概念性的。它仅存在于编译器级别。当编译器翻译源代码时,它会被检查并强制执行。一旦代码被编译,公共数据成员和私有数据成员之间就没有区别了,即没有物理机制可以强制访问控制和阻止对私有数据成员的访问。

编译器根据语言规范强制执行成员访问。语言规范规定类成员函数(无论它们是否内联)可以访问类的私有成员。所以编译器允许这种访问。同时,禁止其他函数进行此类访问,因此编译器会抱怨它。

在您的示例中,您正在从成员函数访问私有数据成员。这是允许的,所以代码编译,即编译器不会抱怨。在函数被内联之后,在生成的机器代码中稍后发生的事情完全无关紧要。这里的所有都是它的。

于 2012-11-02T01:10:09.970 回答
6

您误解了内联的工作原理。编译器内联代码的逻辑,而不是代码的实际文本

谁能解释一下为什么您可以从类外部访问私有数据成员,但是当成员函数是内联的时,尽管内联只是将函数调用替换为函数的内容,但它可以吗?

因为函数的内容就是函数的内容。它们不会因为被内联而不再是函数。您可以从成员函数内部访问私有成员变量。当一个成员函数被内联时,它的代码仍然在成员函数内部,因为该函数是内联的。

于 2012-11-02T00:55:48.213 回答
2

首先,是否内联取决于编译器。在很多情况下,它会决定不是最好的做法。

其次,在它内联它的情况下,它使用编译的二进制文件,C++ 源代码中描述的行为的产物,而不是实际的文本。

于 2012-11-02T00:57:38.577 回答
0

Morbo 说 inline 关键字不是这样工作的。

Morbo 说 inline 关键字表示链接器时涉及此函数的符号冲突应该被忽略,并且所有实现在类声明中的函数都是隐式内联的。

莫博是明智的。你应该听 Morbo,即使 inline 有一个小的技术附加含义,涉及获取地址。

更严重的是,内联只是让您将实现的定义放入头文件中。实际上使代码内联更容易,因为它不必在链接时发生(并且大多数 C++ 链接器都太懒了),但它不会导致代码内联。

最后,隐私是概念性的,它不是由 C++ 运行时强制执行的。它只是在编译时通过告诉您某些内容超出范围来强制执行。

于 2012-11-02T02:51:28.453 回答