C++Day7
静态联编和动态联编
#include <iostream>
using namespace std;
class Animal
{
public:
//虚函数
virtual void speak()
{
cout << "动物在说话" << endl;
}
};
class Cat : public Animal
{
public:
void speak()
{
cout << "小猫在说话" << endl;
}
};
//动态多态产生条件
//现有继承关系
//父类中有虚函数,子类重新父类中的虚函数
//父类的指针或引用 指向子类的对象
//对于有父子关系的两个类 指针或引用是可以直接转换
void doSpeak(Animal & animal)//Animal & animal=cat;
{
animal.speak();//如果地址早就绑定好了,地址早绑定,属于静态联编
//如果想要调用小猫说话,此时函数的地址不能早就绑定好了
//而是应该在运行阶段再去绑定函数地址
//属于地址晚绑定,为动态联编
}
void test01()
{
Cat cat;
doSpeak(cat);//未加虚函数为动物在说话,加了为小猫在说话
}
int main()
{
test01();
return EXIT_SUCCESS;
}
虚函数原理
- 当父类写了虚函数后,类内部结构发生改变,多了一个vfptr
- vfptr虚函数表指针-----》vftable虚函数表
- 虚函数表内部记录虚函数入口地址
- 当父类指针或引用指向子类对象,发生多态。调用是时候从虚函数中找函数入口地址
- 虚函数 关键字 virtual
多态案例
//计算器实现
#include <iostream>
#include <string>
using namespace std;
/*class calculator
{
public:
int getResult(string oper)
{
if (oper == "+")
{
return m_A + m_B;
}
else if (oper == "-")
{
return m_A - m_B;
}
else if (oper == "*")
{
return m_A * m_B;
}
}
int m_A;
int m_B;
};*/
//设计原则:开闭原则
//对扩展进行开放 对修改进行关闭
//利用多态实现计算器
class AbstravtCalculator
{
public:
virtual int getResult()
{
return 0;
}
int m_A;
int m_B;
};
//加法计算器
class AddCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A + m_B;
}
};
//减法计算器
class SubCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A - m_B;
}
};
//乘法计算器
class MulCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A * m_B;
}
};
void test01()
{
/*calculator c;
c.m_A = 10;
c.m_B = 10;
cout << c.getResult("+") << endl;*/
AbstravtCalculator* calculator = new AddCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
delete calculator;
calculator = new SubCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
}
int main()
{
test01();
return EXIT_SUCCESS;
}
纯虚函数和抽象类
#include <iostream>
#include <string>
using namespace std;
/*class calculator
{
public:
int getResult(string oper)
{
if (oper == "+")
{
return m_A + m_B;
}
else if (oper == "-")
{
return m_A - m_B;
}
else if (oper == "*")
{
return m_A * m_B;
}
}
int m_A;
int m_B;
};*/
//设计原则:开闭原则
//对扩展进行开放 对修改进行关闭
//利用多态实现计算器
class AbstravtCalculator
{
public:
//纯虚函数
//如果一个类中包含纯虚函数,那么这个类就无法实例化对象
//这个类称为抽象类
//抽象类的子类必须重写父类中的纯虚函数,否则也属于抽象类
virtual int getResult() = 0;
/*virtual int getResult()
{
return 0;
}*///用纯虚函数替换
int m_A;
int m_B;
};
//加法计算器
class AddCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A + m_B;
}
};
//减法计算器
class SubCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A - m_B;
}
};
//乘法计算器
class MulCalculator : public AbstravtCalculator
{
public:
virtual int getResult()
{
return m_A * m_B;
}
};
void test01()
{
/*calculator c;
c.m_A = 10;
c.m_B = 10;
cout << c.getResult("+") << endl;*/
AbstravtCalculator* calculator = new AddCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
delete calculator;
calculator = new SubCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
}
int main()
{
test01();
return EXIT_SUCCESS;
}
虚析构和纯虚析构
#include <iostream>
#include <string>
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal的构造函数调用" << endl;
}
virtual void speak()
{
cout << "动物在说话" << endl;
}
//如果子类中有指向堆区的属性,那么要利用虚析构技术在delete的时候调用子类的析构函数
/*virtual ~Animal()
{
cout << "Animal的析构函数调用" << endl;
}*/
//纯虚析构需要有声明 也需要有实现
//如果一个类中有了纯虚析构函数,那么此类为抽象类,无法实例化对象
virtual ~Animal() = 0;
};
Animal::Animal()
{
cout << "Animal的纯虚析构函数调用" << endl;
}
class Cat : public Animal
{
public:
Cat(const char* name)
{
cout << "Cat的构造函数调用" << endl;
this->m_Name = new char[strlen(name) + 1];
strcpy(this->m_Name, name);
}
virtual void speak()
{
cout<<this->m_Name << "小猫在说话" << endl;
}
~Cat()
{
if (this->m_Name)
{
cout << "Cat的析构函数调用" << endl;
delete[]this->m_Name;
this->m_Name = NULL;
}
}
char* m_Name;
};
void test01()
{
Animal * animal = new Cat("Tom");
delete animal;
}
int main()
{
test01();
return EXIT_SUCCESS;
}
向上向下类型转换
- 父转子 向下类型转换 不安全
- 子转父 向上类型转换 安全
- 如果发生多态,转换永远是安全的
电脑组装案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//CPU基类
class CPU
{
public:
virtual void calculate() = 0;
};
//显卡基类
class VideoCard
{
public:
virtual void display() = 0;
};
//内存基类
class Memory
{
public:
virtual void storage() = 0;
};
//电脑类
class computer
{
public:
computer(CPU * cpu, VideoCard * vc, Memory * mem)
{
cout << "电脑构造调用" << endl;
this->m_Cpu = cpu;
this->m_Vc = vc;
this->m_Mem = mem;
}
void doWork()
{
this->m_Cpu->calculate();
this->m_Vc->display();
this->m_Mem->storage();
}
~computer()
{
cout << "电脑析构调用" << endl;
if (this->m_Cpu)
{
delete this->m_Cpu;
this->m_Cpu = NULL;
}
if (this->m_Vc)
{
delete this->m_Vc;
this->m_Vc = NULL;
}
if (this->m_Mem)
{
delete this->m_Mem;
this->m_Mem = NULL;
}
}
CPU * m_Cpu;
VideoCard * m_Vc;
Memory * m_Mem;
};
//inter厂商
class intelCPU :public CPU
{
public:
void calculate()
{
cout << "intelCPU开始计算了" << endl;
}
};
class intelVideoCard :public VideoCard
{
public:
void display()
{
cout << "intel 显卡开始显示了" << endl;
}
};
class intelMemory :public Memory
{
public:
void storage()
{
cout << "intel 内存条开始存储了" << endl;
}
};
//Lenovo 厂商
class LenovoCPU :public CPU
{
public:
void calculate()
{
cout << "Lenovo CPU开始计算了" << endl;
}
};
class LenovoVideoCard :public VideoCard
{
public:
void display()
{
cout << "Lenovo 显卡开始显示了" << endl;
}
};
class LenovoMemory :public Memory
{
public:
void storage()
{
cout << "Lenovo 内存条开始存储了" << endl;
}
};
void test01()
{
cout << "第一台电脑组成:" << endl;
CPU * intelCpu = new intelCPU;
VideoCard * lenovoVC = new LenovoVideoCard;
Memory * lenovoMem = new LenovoMemory;
computer c1(intelCpu, lenovoVC, lenovoMem);
c1.doWork();
cout << "第二台电脑组成:" << endl;
CPU * intelCpu2 = new LenovoCPU;
VideoCard * lenovoVC2 = new intelVideoCard;
Memory * lenovoMem2 = new intelMemory;
computer c2(intelCpu2, lenovoVC2, lenovoMem2);
c2.doWork();
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}