虚函数
- 用virtual修饰的函数叫做虚函数
- 特性:虚函数是用一个指针去存储所有虚函数
- 虚函数对类的影响:会增加一个指针类型的字节 (64位:8个字节,32位:4个字节)
- 虚函数表
#include <iostream>
class student
{
public:
void virtual printA()
{
std::cout << "虚函数A" << std::endl;
}
void virtual printB()
{
std::cout << "虚函数B" << std::endl;
}
protected:
int age;
};
int main()
{
student xiaogua;
std::cout << "64位下的类占用字节:" << sizeof(student) << std::endl;
long long** vptr = (long long**)&xiaogua;
typedef void(*Func)();
Func p1 = (Func)vptr[0][0];
p1();
Func p2 = (Func)vptr[0][1];
p2();
return 0;
}
- 运行结果
纯虚函数
虚函数=0;
#include <iostream>
#include <string>
class student
{
public:
virtual void print() = 0;
};
int main()
{
student* pObject = nullptr;
return 0;
}
多态
- C++类中对象指指针或者是引用的同一行为的不同结果,是因为初始化的对象不同导致的结果不同
- 引发多态的情况
- 情况一:父类指针(引用)被子类对象初始化又叫上行转换(无virtual看指针类型,有virtual看对象)
- 情况二:必须具备同名函数并且父类中存在虚函数
- 情况三: 一般是public继承
#include <iostream>
class student
{
public:
void print()
{
std::cout << "父类:print函数" << std::endl;
}
void virtual printVirtual()
{
std::cout << "父类:printVirtual函数" << std::endl;
}
protected:
};
class xiaogua :public student
{
public:
void print()
{
std::cout << "子类:print函数" << std::endl;
}
void printVirtual()
{
std::cout << "子类:printVirtual函数" << std::endl;
}
protected:
};
int main()
{
student boy;
xiaogua mm;
boy.print();
boy.printVirtual();
mm.print();
mm.printVirtual();
std::cout << std::endl;
student* pB = new student;
xiaogua* pM = new xiaogua;
pB->print();
pB->printVirtual();
pM->print();
pM->printVirtual();
std::cout << std::endl;
student* pX = new xiaogua;
std::cout << "无virtual看指针类型:";
pX->print();
std::cout << "有virtual看对象:";
pX->printVirtual();
return 0;
}
- 运行结果
虚析构函数
- virtual修饰的析构函数叫做虚析构函数
- 当用子类对象初始化父类指针的时候,父类需要虚析构函数
#include <iostream>
class student
{
public:
student()
{
std::cout << "构造函数student" << std::endl;
}
virtual ~student()
{
std::cout << "析构函数student" << std::endl;
}
protected:
};
class xiaogua :public student
{
public:
xiaogua()
{
std::cout << "构造函数xiaogua" << std::endl;
}
~xiaogua()
{
std::cout << "析构函数xiaogua" << std::endl;
}
protected:
};
int main()
{
student* pStu = new xiaogua;
delete pStu;
return 0;
}
- 运行结果
ADT:抽象数据类型
- 抽象类的使用,抽象类不能创建的对象,但是可以创建对象指针结合子类初始化父类指针的操作
- 继承父类的子类没有实现父类的纯虚方法,子类也是抽象类,不能构建对象
#include <iostream>
class Window
{
public:
Window() {}
void push_back(Window* pWindow = nullptr)
{
windows[size++] = pWindow;
}
virtual void PressMouse()
{
std::cout << "默认按鼠标" << std::endl;
}
virtual void MouseMove()
{
std::cout << "默认鼠标移动" << std::endl;
}
virtual void show()
{
for (int i = 0; i < size; i++)
{
std::cout << "窗口显示:" << windows[i]->w << " " << windows[i]->h << std::endl;
}
}
virtual ~Window(){}
protected:
Window* windows[8];
int size = 0;
int w;
int h;
};
class Button:public Window
{
public:
Button() {}
Button(int w, int h, Window* pWindow)
{
this->w = w;
this->h = h;
pWindow->push_back(this);
}
void MouseMove()
{
std::cout << "画线" << std::endl;
}
~Button() {}
};
int main()
{
Window* parent = new Window;
Window* p = new Button;
Button* button1 = new Button(100, 200, parent);
Button* button2 = new Button(300, 400, parent);
Button* button3 = new Button(500, 600, parent);
p->MouseMove();
parent->show();
return 0;
}
- 运行结果
继承中的两个关键字
- final:禁止重写
- override:重写检查,检查是否是重写函数,不是直接报错
#include <iostream>
class student
{
public:
virtual void print() final
{
std::cout << "禁止重写" << std::endl;
}
virtual void printData()
{
std::cout << "重写检查" << std::endl;
}
protected:
};
class xiaogua:public student
{
public:
void printData() override
{
std::cout << "直接检查是否是重写函数" << std::endl;
}
};
int main()
{
return 0;
}
拓展:从设计模式角度看待多态,工厂模式
- 抽象工厂类
- 具体工厂类—>创建产品
- 提供抽象产品类
- 具体产品类
#include <iostream>
class AbstractProduct
{
public:
virtual void make() = 0;
};
class AbstractFactory
{
public:
virtual AbstractProduct* creatProduct() = 0;
};
class student :public AbstractProduct
{
void make()
{
std::cout << "创建学生小瓜" << std::endl;
}
};
class studentFactory :public AbstractFactory
{
public:
AbstractProduct* creatProduct()
{
return new student;
}
};
class studentXiaoming :public AbstractProduct
{
public:
void make()
{
std::cout << "创建学生小明" << std::endl;
}
};
class studentXiaomingProduct :public AbstractFactory
{
public:
AbstractProduct* creatProduct()
{
return new studentXiaoming;
}
};
int main()
{
AbstractFactory* factory = new studentFactory;
AbstractProduct* studentProduct = factory->creatProduct();
studentProduct->make();
factory = new studentXiaomingProduct;
AbstractProduct* xiaoming = factory->creatProduct();
xiaoming->make();
return 0;
}
- 运行结果
- 插语:
- factory:n.工厂,制造厂;
- product:n.产品,制品;
- abstract:adj.抽象的,纯概念的;