1.public、private、protected
- public:
- private: 该类型的创建者及类内其他成员变量
- protected:在private基础上,增添继承的结构也可以访问
2.友元friend
在结构体内部声明不属于当前结构体的函数为friend(友元),则该函数可以访问当前结构中的数据。
程序员可以把一个全局函数声明为friend,也可以把另一个结构中的成员函数甚至整个结构都声明为friend:
//Friend allows special access
//注意结构体X跟Y的定义顺序,及Y::f()的参数X*
struct X;
struct Y {
void f(X*); // 由于程序仅仅声明了strcut X,所以目前还不可以引用除结构体X名字以外的任何信息,Y:f(X*)的重写,必须在strcut X定义结束之后
};
struct X {
private:
int i;
public:
void initialize();
friend void g(X*, int); //global friend
friend void Y::f(X*); //Struct member friend
friend struct Z; //Entire struct is a friend
friend void h();
};
void X::initialize() {
i = 0;
}
void g(X* x, int i){
x->i = i;
}
void Y::f(X* x) {
x->i = 47;
}
struct Z {
private:
int j;
public:
void initialize();
void g(X* x);
};
void Z::initialize(){
j = 99;
}
void Z::g(X* x){
x->i += j;
}
void h(){
X x;
x.i = 100; //Direct data manipulation
}
int main() {
X x;
Z z;
z.g(&x);
}
有一条必须满足的规则是:struct Y必须在它的成员Y::f(X*)在被声明为strcut X的友元前声明。
- 注意到Y::f(X*)引用了X对象的地址。通过传递X的地址,编译器允许程序员在声明Y::f(X*)之前做一个X的不完全的类型说明。这一点是用如下的声明时完成的:struct X;该声明仅仅是告诉编译器,有一个较X的struct,所以当它被引用时,只要不涉及名字以外的其他信息,就不会产生错误。
- 由于程序仅仅声明了struct X,所以目前还不可以引用除结构体X名字以外的任何信息,Y:f(X*)的重写,必须在strcut X定义结束之后。
- 在struct X声明全局函数g()或struct Z为friend前,并未将二者在全局范围内作过声明。这表明friend可以在声明函数的同时又将它作为struct的友元。
综述:在结构体声明某函数或某结构体为friend前,并不需要在全局进行声明,但倘若是声明另外个结构体的函数为friend时,必须先声明这个"另外个结构体"
3.嵌套友元
嵌套的结构不属于这个类的成员变量,不能自动获得访问private成员的权限,需要使用友元嵌套:首先声明一个嵌套结构,然后声明它是全局范围使用的friend,最后定义这个结构。
const int sz = 20;
struct Holder{
private:
int a[sz];
public:
void initialize();
struct Pointer; //先声明一个嵌套结构体
friend Pointer; //再声明它是全局范围使用的一个friend
struct Pointer {
//定义嵌套结构体
private:
Holder* h;
int* p;
public:
void initialize(Holder* h);
void next();
void previous();
void top();
void end();
int read();
void send(int i);
};
};
- 注:C++不是纯面向对象,它追求的是实用,而不是理想的抽象。
4.类
- class的成员默认为private,struct的成员默认为public