public 所有均可访问
private 类自己的成员函数访问,不能被类对象访问
protected 类自己以及子类访问,不能被类对象访问
friend 友元,别人是你的朋友,他可以访问我的东西。(但不是我可以访问他的东西)
- 友元关系不能被继承。
- 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
- 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
- 友元函数并不是类的成员函数,因此在类外定义的时候不能加上class::function name
例子1
#include <iostream>
using namespace std;
class A {
private:
int i;
public:
A() {i = 0; cout <<"A::A"<<endl; }
~A() {i = 0; cout <<"A::~A"<<i<<endl; }
void set(int i) {this->i = i;}
void g(A *q) { cout << q->i << endl; }
};
int main ()
{
A a;
A b;
b.set(100);
a.g(&b); // 使用对象a的成员函数访问对象b中的私有变量i,则不能通过对象直接访问
return 0;
}
结果
备注:
- private,protected限制编译时刻检查,而不是运行检查。一直编译成二进制,则不再受到此限制。
- struct 缺省权限是public, class缺省权限是private
- C++中,只有成员变量很简单数量少才可能使用struct;一般使用class
例子2-protected
#include <iostream>
using namespace std;
class A {
public:
int a = 1;
private:
int b = 2;
protected:
int c = 3;
};
class B: public A
{
public:
void func()
{
std::cout << A::a << std::endl; // 可通过A类访问公有变量
// std::cout << A::b << std::endl; // 不能在B类中通过A类访问私有变量
std::cout << A::c << std::endl; // 可通过A类访问保护变量
}
};
int main()
{
B b;
A a;
cout << b.a << a.a << endl; // 可通过A类变量访问共有变量
// cout << b.c << a.c << endl; // 不可通A过类变量访问保护变量
return 0;
}
注:
- 类中省略public 等时,默认是private属性
- 继承基类, 在基类前省略public 等时, 默认是protected属性
例子3-友元函数,外部调用可访问类的变量和方法
#include <iostream>
#include <math.h>
using namespace std;
class Point
{
public:
Point(double xx, double yy) { x=xx; y=yy; } //默认构造函数
void Getxy(); //公有成员函数
friend double Distance(Point &a, Point &b); //友元函数
private:
double x, y;
int key = 101;
public:
int kk = 102;
};
void Point::Getxy()
{
cout<<key<<endl; // 函数定义中访问私有变量
}
double Distance(Point &a, Point &b) // 友元定义,注意函数名前未加类声明符
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx+dy*dy);
}
int main()
{
Point p1(3.0, 4.0), p2(6.0, 8.0);
p1.Getxy();
// cout << p2.key << endl; 不能访问私有变量
// cout << Point::key << endl; 不能访问非静态变量
cout << p2.kk << endl;
double d = Distance(p1, p2); // 友元访问
cout<<"Distance is: "<<d<<endl;
return 0;
}
结果:
例子4-友元类,外部调用可访问类的变量和方法
当一个类作为另一个类的友元时,它的所有成员函数都是另一个类的友元函数,都可以访问另一个类的私有或者公有成员
友元作为参数与使用类指针作为参数的区别在于,友元可以访问类的私有成员
#include <iostream>
#include <cstring>
using namespace std ;
//声明教师类
class Techer ;
//学生类
class Student
{
private:
string name ;
int age ;
char sex ;
int score ;
public :
Student(string name , int age , char sex , int score);
void stu_print(Techer &tech);
};
//教师类
class Techer
{
private:
string name ;
int age ;
char sex ;
int score ;
public :
Techer(string name , int age , char sex , int score);
//声明一个友元类
friend Student ;
};
//Student类的构造函数的实现
Student::Student(string name , int age , char sex , int score)
{
this->name = name ;
this->age = age ;
this->sex = sex ;
this->score = score ;
}
//Techer类的构造函数的实现
Techer::Techer(string name , int age , char sex , int score)
{
this->name = name ;
this->age = age ;
this->sex = sex ;
this->score = score ;
}
//打印Student类中的私有成员和Techer的私有成员
void Student::stu_print(Techer &tech)
{
//用this指针访问本类的成员
cout << this->name << endl ;
cout << this->age << endl ;
cout << this->sex << endl ;
cout << this->score << endl ;
//访问Techer类的成员
cout << tech.name << endl ;
cout << tech.age << endl ;
cout << tech.sex << endl ;
cout << tech.score << endl ;
}
int main(void)
{
Student stu1("YYX",24,'N',86);
Techer t1("hou",40,'N',99);
stu1.stu_print(t1);
return 0 ;
}
结果
备注:
- 运算符重载经常使用friend
- friend写在类声明中,一旦类实现完成,则不能再添加friend
- friend的授权在编译期