总所周知,在一个class中,其三层访问权限为:外界只能访问public成员,其子类可以访问protected和public成员,自己可以访问private,protected和public。但是,下面的例子是一个奇怪的反例。
1: class A
2: {3: public:
4: A() : x(0) {}5: int foo(A a)
6: {7: return this->x + a.x;8: }9: private:
10: int x;
11: };12:13: class B
14: {15: public:
16: B() : y(0) {}17: protected:
18: int y;
19: };20:21: class C : public B22: {23: public:
24: C() {}25: int bar(B* b)
26: {27: return this->y + b->y;28: }29: };30:31: int main()
32: {33: A a1, a2;34: a1.foo(a2);35:36: B b;37: C c;38: c.bar(&b);39: return 0;
40: }编译时,你会发现,foo的调用是对的,但是bar的调用出错。告诉你`int B::y’ is protected。这里问题就来了。C继承B,那么相应继承了B的成员y,为什么就不能用b->y的形式呢。当然不能,原因编译器已经给出,protected成员只能通过子类来直接访问,例如c->y,但是对于b->y的形式,相当于外界访问,这是不允许的。那么又有问题了,A::foo中,就可以在外界直接访问A::x,例如a.x,但是A::x是private,应该只能在类内通过this->x访问,不能通过a.x来访问,要访问应该加上a.get_x()这样的函数。问题就在这里。
在C++中,类的三层访问权限是本类对于外类来说的。就是说,我有一个class A,对于另一个class B来说,其objects可以访问A的objects的public成员;若B是A的子类,那么同时也可以其访问protected成员。但是,对于同属于A类的所有objects,它们之间是可以访问所有成员的。举个例子,同一个班级的学生可以看到自己班级里的任何东西(class A的所有objects互访所有信息),不属于本班的学生就只能看到被公布出来的信息(class B的所有objects只能看到A的public信息)。但是两个班有些共享信息(protected部分),但只能通过特定的手段来看(B的objects来访问),不能直接看(直接通过A的objects来访问)。
为什么这样做呢?对于内部不设防,有一定关系的通过一定方法访问,其它没有联系的一概拒绝。首先,对于同类objects间的访问,这是拷贝构造函数得以实现的关键,不然你没有办法通过A的另一个object来构造新的object,因为无法访问private成员。也许会说,只要用get,set便好。但是这白白增加了函数调用负担,而且如果没有写get/set呢,岂不是什么也不能做。所以,对于类内,一切都是可见的。对于类外,当然,有保留地访问,可以有效封装,增加安全性。
这个问题来自云风的博客,看了他的解释“所谓私有,是针对类的,而不是具体的对象”,没有明白,干脆自己写,再问问身边的人,仔细想想,大概明白了。