如下,Hair类就是Cat的一个成员的变量类型
class Hair{
public:
string color;
int length ;
bool isSoft;
};
class Cat{
public:
Hair catHair;
int lengthOfLegs;
string colorEyes;
};
int main() {
Cat cat1;
cat1.catHair.length=20;
cat1.lengthOfLegs=10;
cat1.colorEyes="blue";
cout<
输出如下
this is Hair constructor
this is Cat constructor
20
this is Cat destructor
this is Hair destructor
- 在实例化Cat前不需要先实例化Hair
- 首先构造析构的顺序是:构造Cat,构造Hair,析构Hair,析构Cat
静态成员变量
-
静态成员需要在类内部声明,类外部初始化,int People::height=190;这条语句表示的意思是设置People作用域下的成员变量.
-
静态成员可以直接使用类名访问,比如cout<
-
静态成员的值被所有的对象共享,如果A修改了,B获取到的也是修改后的值,详见下面的程序,p2修改了height的值,使用p1查看值,也是发生了变化。
#include "iostream"
using namespace std;
class People{
public:
int age;
static int height;
};
int People::height=190;
int main(){
People p1;
p1.age=90;
p1.height=180;
cout<<"p1 age:"<
静态成员函数
- 静态成员函数只能访问静态变量
- 静态成员函数可以通过类名访问
对象模型
-
类中的成员变量和函数是分开存储的
-
类中的非静态成员变量是属于对象的
-
类中的非静态函数,静态函数,静态成员变量都不属于对象
-
this指针指向被调用的成员函数所指的对象:谁调用函数,this就指向谁,可以用来解决重名冲突
-
在非静态成员函数中返回成员本身
-
空指针可以访问成员函数
People *p = NULL;
p->speak();
常函数和常对象
- 常(const)函数内不可以修改成员属性
- 常(const)函数可以修改添加了mutable关键字的成员属性
- 常对象只可以调用常函数
友源
- 全局函数做友元:在类内部使用friend关键字对全局函数进行声明,则全局函数就可以访问类中的私有成员属性。
- 类做友元:在类内部使用friend关键字对类进行声明。
- 成员函数做友元:在类内部使用friend关键字对成员函数进行声明,注意加上::限制范围。
运算符重载
使用operator关键字
继承
A是B的子类(派生类)
B是A的父类(基类)
class A:class B;
- 父类中的所有的属性都会被继承
- 构造和析构顺序:父构造,子构造,子析构,父析构
- 子类和父类的同名属性:默认是子类,添加作用域(::)是父类
- 子类和父类的同名函数(包括重载的):默认是子类,添加作用域(::)是父类
- 静态成员属性继承:同上
多态
- 在父类的成员函数添加virtual关键字,成为虚函数,则父类引用指向子类的问题可以解决:根据传入对象的不同,选择不同的执行函数
- 动态多态:有继承关系,子类重写父类的虚函数,父类的指针或者引用指向子类的对象
- 虚函数表继承后覆盖地址(参考黑马视频)
- 虚函数和纯虚函数,具有纯虚函数的类称为抽象类,纯虚函数:virtual void func() = 0
- 虚析构:解决父类不可以释放子类的空间,在子类的析构函数前加上virtual关键字就可解决这个问题
- 纯虚析构:纯虚析构可以解决上面的问题,纯虚析构必须要实现,有了纯虚析构函数的类就是抽象类。



