静态成员
静态成员是指声明为static的类成员在类的范围内所有对象共享某个数据。
静态数据成员的定义与一般数据成员相似,但前面要加上static关键词。
静态数据成员的初始化与一般数据成员不同,静态数据成员初始化的格式如下:
<类型> <类名>::<静态数据成员>=<值>;
在引用静态数据成员时采用格式:
<类名>::<静态数据成员>
静态成员函数不得说明为虚函数。静态成员函数与静态数据成员类似,也是从属于类,不属于对象。
<类名>::<静态成员函数名>(<参数表>);
静态成员函数只能访问静态数据成员、静态成员函数和类以外的函数和数据,不能访问类中的非静态数据成员(因为非静态数据成员只有对象存在时才有意义)。
静态成员函数没有this指针,若要访问类中的非静态成员时,必须借助对象名或指向对象的指针。
友元
友元函数
友元是一种定义在类外部的普通函数,但它需要在类的内部进行说明,为了与该类的成员函数加以区别,在说明时前面加上关键字friend。
友元不是成员函数,但它可以访问类中的私有成员。其作用是提高程序的运行效率。
C++语言中的友元函数为在类外访问类中的私有成员和保护成员提供了方便,但破坏了类的封装性和隐蔽性。友元可以是一个函数,称为友元函数,也可以是一个类,称为友元类。友元函数和友元类统称为友元。
声明 格式如下:
friend <类型> <友元函数名> (<参数表>);
友元函数说明的位置可在类的任何部位,既可在public区,也可在protected区(private 也可以),意义完全一样。
定义 格式和普通函数一样,不需要类名限制,定义则在类的外部,不能放到类内定义(c++规范中是允许的),一般与类的成员函数定义放在一起。
调用 可以像普通函数一样在任何地方调用,不需要由类的实例来调用。
友元类 friend class
如果A是B的友员类,则A中的所有成员函数可以像友员函数一样访问B类中的所有成员。定义格式如下:
class B
{ friend class A; //A的所有成员函数均为B的友员函数
…
}
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。
继承
基类(父类)、派生类(子类)。默认剪头方向指向基类
成员的访问权限:
public:用该关键字修饰的成员表示公有成员,该成员不仅可以在类内可以被访问,在类外也是可以被访问的,是类对外提供的可访问接口;
protected:用该关键字修饰的成员表示保护成员,保护成员在类体外同样是隐藏状态,但是对于该类的派生类来说,相当于公有成员,在派生类中可以被访问。
private:用该关键字修饰的成员表示私有成员,该成员仅在类内可以被访问,在类体外是隐藏状态;
class <派生类>:<继承方式> <基类> {};
继承的访问权限:
public继承方式,基类成员在派生类中的访问权限保持不变,派生类的成员可以访问基类的公有成员和保护成员,派生类的对象可以访问基类的公有的成员;
protected继承方式,基类的公有成员和保护成员,在派生类中的访问权限都会变为保护(protected)权限,即只允许成员访问,私有成员在派生类中的访问权限为不可访问。
private继承方式,基类的公有成员和保护成员,在派生类中的访问权限都会变为私有 private权限,即只允许成员访问,私有成员在派生类中的访问权限为不可访问。
总的来说,对于基类的私有成员,只能被基类中的成员函数和友元函数访问,不能被其他函数访问。
继承 成员 | 公有 | 保护 | 私有 |
公有 | 公有 | 保护 | 私有 |
保护 | 保护 | 保护 | 私有 |
私有 | 不可访问 | 不可访问 | 不可访问 |
访问声明:派生类中使用 "类名::成员"访问基类成员。
派生类可以覆写基类成员函数,默认调用派生类。
单继承:派生类只有一个基类。
构造函数不能被继承,派生类的构造函数必须调用基类的构造函数初始化基类子对象或编译器默认调用,建议手动调用。
派生类构造函数的一般格式如下:
<派生类名> (<派生类构造函数总参数表>)
: <基类构造函数> (<基类构造函数总参数表>)
, <子对象名> (<参数表>) // 派生类的子对象
, <成员变量赋值>
{
<派生类数据成员初始化>;
}
派生类构造函数的调用顺序:
基类的构造函数(多个取决于构造中定义顺序)、子对象的构造函数、派生类的构造函数。
析构函数也是不能被继承的,执行顺序和构造相反。
多继承
class <派生类>:<继承方式> <基类1>, <继承方式><基类2> {};
二义性问题:obj.A()::get();
赋值兼容规则:(公有派生,假定derived 由 base 派生)
派生类的对象可以赋值给基类的对象。
derived d;
base b;
b = d;
派生类的对象可以初始化基类的引用。
derived d;
base &br = d;
派生类的对象地址可以赋值给指向基类的指针。
derived d;
base *pb = &d;
虚继承:
class A;
class B1:public virtual A;
class B2:public virtual A;
class D:public B1,public B2;
c++ 规定,在一个成员列表中出现对虚基类和非虚基类构造函数的调用,则虚基类构造函数先于非虚基类的构造函数执行。