废话不多说, 先看看下面的代码!
class ClassA
{
private:
int m_a;
public:
void copy(const ClassA &other)
{
m_a = other.m_a;
}
}
很多人会问了m_a 是类 ClassA 的私有成员变量, 为什么 ClassA 的对象 other 可以直接访问私有成员变量 m_a呢?
本人开始也很疑惑! 其实不止c++, java 也是这样的情况.
网上查了一下, 没有满意的答案, 我把《C++PL》,《C++ Primer Plus 第五版》,《C++ Primer 第四版》翻出来看看.
最后在《C++ Primer 第四版》7.7.1 定义成员函数的函数体 这一节找到答案了.
ClassA 的成员函数 copy 可以访问 private 成员 m_a, 这个很多人都不会有疑问的.
让我们来把 copy 写得更完整:
void copy(const ClassA &other)
{
this->m_a = other.m_a;
}
this 指针相信很多人都用过, 但是有些人可能不知道它是怎么来的了.
看看编译器对这段代码的处理:
void copy(ClassA *this, const ClassA &other)
{
this->m_a = other.m_a;
}
这样看起来就清楚了吧, this 指针不是凭空出现的, this指针能访问 m_a, 那 other 对象当然也能访问 m_a; 如若不然, 就是两者都不能访问 m_a 了, 相信C++ 的作者也不想这样吧.
每个非静态的成员函数(包括构造函数和析构函数) 都有一个 this 指针. this 指针指向调用对象.
对 this 指针有疑问, 可以看看 《C++ Primer Plus 第五版》10.4 this 指针 这一节.
在《C++PL》10.2.2 访问控制 这一节写到
1. "直接依赖于Date 的表示的全部函数, 是仅有的能够直接访问Date 类的对象的函数."
2. "私有部分(private)只能由成员函数使用; 公用部分(public)则构成了该类的对象的公用界面."
3. "对私有成员的保护依靠的是对于使用类成员名称的限制. 可以通过地址操作和显示的类型转换等绕过这些限制. C++ 的保护只是为了避免无意的失误, 而不是为了防止精心策划的计谋(骗局)."
在《C++ Primer 第四版》7.7.1 节有句注解写到 "类的成员函数可以访问该类的 private 成员."
换句话来说, 就是 "类的成员函数是可以访问该类的对象的 private 成员的".
private 的保护作用只是在编译前和编译过程中有用, 编译后的机器代码可是完全没有public 和 private 之类关键字的. 所以你不要指望 private 能在程序运行时起作用.
lin49940
参考: 《C++PL》10.2.2 访问控制
《C++ Primer 第四版》7.7.1 定义成员函数的函数体
12.2 隐含的 this 指针
《C++ Primer Plus 第五版》10.4 this 指针