c++类访问权限及友元
1.类的访问权限
class是c++的类声明关键字,它的成员类型有三种,是使用三个关键字来声明的,分别是public、private、protected,public声明的叫做公有成员,private声明的是私有成员,protected声明的则是保护成员。
1)public-公有成员
首先看一下public声明的公有成员:
class A
{
public:
int a;
int b;
public:
int add();
private:
int sub();
protected:
int mul();
};
int A::add()
{
return a+b;
}
int A::sub()
{
return a-b;
}
int A::mul()
{
return a*b;
}
int main()
{
A a;
a.a = 2;
a.b = 3;
return 0;
}
对于以上代码,编译通过,说明对于公有成员a和b,公有成员函数、私有成员函数、保护成员函数以及类对象都是可以直接进行访问的。
2)private-私有成员
接下来将成员变量a声明为私有,如下:
class A
{
private:
int a;
public:
int b;
public:
int add();
private:
int sub();
protected:
int mul();
};
int A::add()
{
return a+b;
}
int A::sub()
{
return a-b;
}
int A::mul()
{
return a*b;
}
int main()
{
A a;
a.a = 2;
a.b = 3;
return 0;
}
编译时报错如下:
test.cpp: In function ‘int main()’:
test.cpp:33:4: error: ‘int A::a’ is private within this context
编译报错的意思是第33行,a是一个私有成员,不能直接访问,那么将33行注释掉,然后再编译,可以通过。
综上,说明对于私有成员a,公有成员函数、私有成员函数、保护成员函数都可以直接进行访问,但类对象不能直接访问。
3)protected-保护成员
同上,将a声明为protected类型,结果与声明为private是一致的,说明至少在这个类本身以及它的对象而言,private和protected作用是一致的。
接下来声明一个类B,公有继承类A,看一下结果怎么样:
class A
{
protected:
int a;
private:
int b;
public:
int add();
private:
int sub();
protected:
int mul();
};
int A::add()
{
return a+b;
}
int A::sub()
{
return a-b;
}
int A::mul()
{
return a*b;
}
class B : public A
{
B()
{
a = 2;
}
};
int main()
{
A a;
//a.a = 2;
//a.b = 3;
return 0;
}
a为保护成员,b为私有成员,子类B直接访问a,编译通过。
然后将a改为b,编译报错如下:
test.cpp: In constructor ‘B::B()’:
test.cpp:34:3: error: ‘int A::b’ is private within this context
从这里看,对于子类而言,私有成员和保护成员的访问权限是不同的。
综上所述,public说明在它后面声明的所有成员对类的所有成员以及所有类对象都是可以存取的,private说明只有类的内部成员函数可以存取,类对象以及指针都是不允许直接访问的,protected与private基本相似,唯一的一点不同是父类定义的private成员,子类不可以访问,但是父类定义的protected成员,子类是可以访问的。
另外在struct中,也是可以使用这三个关键字的,用法与class基本一致,不同之处是,如果struct某个成员没有指明类型,那么默认是public的,而class默认是private的。
2.友元
如果想允许不属于当前类的一个函数存取当前类中的成员,那么要怎么才能做到呢,答案是友元。所谓友元,顾名思义是我们成为朋友了,关系已经比较亲近了,可以适当的参与对方的生活了。友元关键字是friend,我们可以在一个类的内部声明一个友元函数、友元类,或者A类的成员函数也可以被声明为B类的友元。
首先声明一个友元函数,如下:
class A
{
protected:
int a;
private:
int b;
protected:
int c;
public:
//友元函数不属于类的成员,所以它不受其所在类的声明区域public,private,protected的影响
friend void g(A* a, int x);
};
void g(A* a, int x)
{
a->a = x;
a->b = x;
a->c = x;
}
int main()
{
return 0;
}
编译通过,那么说明一个友元函数访问类的公有、私有以及保护成员都是不受限制的。
下面声明友元类,如下:
class A
{
protected:
int a;
private:
int b;
protected:
int c;
public:
//友元函数不属于类的成员,所以它不受其所在类的声明区域public,private,protected的影响
friend void g(A* a, int x);
friend class B;
};
void g(A* a, int x)
{
a->a = x;
a->b = x;
a->c = x;
}
class B
{
public:
B(A *a, int x)
{
a->a = x;
a->b = x;
a->c = x;
}
};
int main()
{
A *a = new A();
B b(a, 2);
return 0;
}
编译也可以通过,那么说明对于友元类而言,类的私有成员和保护成员都是可以直接被访问的。
对于在类中被声明为友元的对象而言,不论是类的公有、私有还是保护成员,都是可以直接访问的。