多态
1,多态的基本概念
多态分为两类
a,静态多态,函数重载和运算符重载属于静态多态,复用函数名
b,动态多态:派生类和虚函数实现运行时多态
静态多态和动态多态的区别:
静态多态的函数地址早绑定,编译阶段确定函数地址
动态多态的函数地址晚绑定,运行阶段确定函数地址
多态满足条件
1,有继承关系
2,子类重写父类中的虚函数
多态的使用:父类指针或引用指向子类对象
重写:函数返回值类型 函数名 参数列表 完全一致称为重写
运用多态的优点
1,代码组织结构清晰
2,可读性强
3,利于前期和后期的扩展以及维护
#include<iostream>
using namespace std;
class caculator
{
public:
virtual int result(int a,int b)
{
return 0;
}
public:
int m_a;
int m_b;
};
class add:public caculator
{
public:
int result(int a,int b)
{
return a+b;
}
};
class sub:public caculator
{
public:
int result(int a,int b)
{
return a-b;
}
};
class mul:public caculator
{
public:
int result(int a,int b)
{
return a*b;
}
};
void test(caculator &a)
{
cout<<a.result(a.m_a,a.m_b)<<endl;
}
void test(caculator *a)
{
cout<<a->result(a->m_a,a->m_b)<<endl;
}
int main()
{
/* add c;
c.m_a=100;
c.m_b=200;
test(c);
sub c1;
c1.m_a=100;
c1.m_b=200;
test(c1);
mul c2;
c2.m_a=100;
c2.m_b=200;
test(c2);
*/
add *c = new add;
c->m_a=100;
c->m_b=200;
test(c);
sub *c1 = new sub;
c1->m_a=100;
c1->m_b=200;
test(c1);
mul *c2 = new mul;
c2->m_a=100;
c2->m_b=200;
test(c2);
delete c;
delete c1;
delete c2;
return 0;
}
2,纯虚构与抽象类
a,当类中有了纯虚函数,这个类也称为抽象类
抽象类特点
无法实例化对象
子类必须重写抽象类中的纯虚函数,否则也属于抽象类
#include<iostream>
using namespace std;
class base
{
public:
virtual int test()=0;//纯虚数的使用语法
};
class son:public base
{
public:
virtual int test()
{
cout<<"this is son rewrite of function"<<endl;
return 0;
}
};
int main()
{
son k;
k.test();
return 0;
}
3,虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码。
解决方法:将父类中的析构函数改为虚析构或者纯虚析构
虚析构与纯析构共性:可以解决父类中指针释放子类对象,都需要有具体函数实现
如果是纯虚析构,该类是抽象类无法实例化对象。
#include<iostream>
#include<string>
using namespace std;
class animal
{
public:
animal()
{
cout<<"this is the animal C"<<endl;
}
/* virtual ~animal()//虚析构
{
cout<<"this is the animal D"<<endl;
}
*/
virtual ~animal()=0;
virtual void test1()=0;//纯虚析构
};
animal::~animal()
{
cout<<"this is the animal D"<<endl;
}
class cat:public animal
{
public:
virtual void test1()
{
cout<<*name<<"maomao"<<endl;
}
cat(string name1)
{
name= new string(name1);
cout<<"this is the cat C"<<endl;
}
~cat()
{
if(name!=NULL)
{
delete name;
}
cout<<"this is the cat D"<<endl;
}
public:
string *name;
};
void test(animal *a)
{
a->test1();
}
int main()
{
animal *a=new cat("tom");
test(a);
delete a;
return 0;
}