1 基本的访问控制
public,protect,private的访问控制级别依次升高,可以从是否外部可以访问 和 是否可继承这两个方面来进行区别。
另外,virtual,friend修饰的函数也会影响访问的控制。
2 友元(friend)
友元函数不属于对象本身,为独立的全局函数,但是可以访问对象的private,protected成员。
目的在于解决外部不能访问对象私有(private)成员的问题。
3 虚函数(virtual)
虚函数的目的在于实现重写(override),进而实现运行时绑定--多态。
这部分比较复杂,可以参考:多态的底层机制
4 静态(static)
在类中的静态变量只是声明,需要在外部定义,且不属于对象,使用时直接通过类去访问。
静态函数成员,同样不属于对象,直接使用类名进行访问。
所以,静态的成员,实际上相当于全局,这在一定程度上有悖于 面向对象的思想。
当然,全局的优势在于可以节约资源。
5 this指针
this指针只能在类的非静态函数中使用,由编译器自动添加到函数的形参中,这里属于隐含(implict)形参。
作用在于通过指向对象的指针,可以访问到类中的成员变量,通过指针的偏移,高效的访问成员进行运算。
6 代码测试
***源码详解见注释***
#include <stdio.h>
#include <iostream>
using namespace std;
class A
{
public:
A(){ pub_i = 10; pro_i = 20; pri_i = 30;}
~A(){}
//this指针,隐含(implict)存在于非静态成员函数的形参中,其指向实例化的对象。
//因为不同对象的函数体是共用的,而函数中使用的成员变量是各自对象拥有的,
//所以通过this指针来访问各自对象中的成员变量
//至于静态成员函数和变量,它本身不属于对象自身,所以无法使用this来访问
void pub_f(){cout << " A pub_f " << this->pub_i << endl;}
int pub_i;
static int s_i; //这里只是声明,若需使用,必须在其他地方进行定义,否则链接失败
//静态成员不属于对象
static void pub_std_f(){cout << " A pub_static_func " << s_i << endl;}
//友元函数,可以访问类中的private,protected成员
friend void fri_f(A *a){cout << " A fri_f " << a->pri_i << " " << a->pro_i << endl;}
protected:
void pro_f(){cout << " A pro_f " << pro_i << endl;}
int pro_i;
private:
void pri_f(){cout << " A pri_f " << pri_i << endl;}
int pri_i;
};
class B : public A
{
public:
B(){}
~B(){}
void pro_fb(){pro_f();} //子类继承了pro_f,故可以使用
void pub_f(){cout << " B pub_f " << endl;} //与父类的成员函数同名,会直接覆盖 父类的函数。。
void pub_af(){pub_f();} //调用子类中的函数pub_f,而非继承的pub_f
};
//定义,并初始化静态成员
int A::s_i = 10;
int main()
{
A *a = new A();
a->pub_f();
a->pub_i;
//a->fri_f(); //友元函数不属于对象的成员函数,不能通过对象访问
fri_f(a); //直接通过函数名调用友元函数,进而访问到对象中的private成员,Protected成员
A::pub_std_f();//直接使用类 访问静态成员函数
B *b = new B();
b->pro_fb();
b->pub_af();
cout << A::s_i << endl; //使用类直接访问静态成员
return 0;
}
7 编译,执行