最近温习了一下c++,本文主要是对c++中一些虚的概念进行一下简单的整理和比较,c++是面向对象的这个大家都知道,既然面向对象那就肯定离不开继承和多态。
继承,只要你学习过面向对象的语言肯定就知道这个概念了,c++和其他一些高级语言不同的是c++中可以多继承(c#,java等不允许多继承),那么多继承就会出现一个问题,嘛问题,看代码吧:
class Employee {//职工
public:
void pay()//支付月薪
{
cout<<"哎呀,employee,要发工资了"<<endl;
}
};
class Technical: public Employee {//技术,也是职工
};
class Manager: public Employee {//经理,也是职工
};
class TechnicalManager:public Technical,public Manager {//技术经理,也是职工
};
int main(int argc, const char * argv[])
{
TechnicalManager tManager;
tManager.pay();//此处编译错误
return 0;
}
上面的代码很简单,之所以出现错误是因为TechnicalManager中存在两个pay函数(一个是Technical类中的pay,另一个是Manager类中的pay),通过TechnicalManager的对象tManager来调用pay,编译器不知道应该调用那个pay,所以编译器就会爆出错误,如果代码改为tManager.Technical::pay()或者tManager.Manager::pay()编译器就不会报错,就是说子类TechnicalManager对象在内存中同时存在pay的两份copy,但是很多情况下我们只需要一个这样的数据copy,多分拷贝增加了内存的开销,这就引入了本文的第一种“虚”
1,虚基类
说白了,虚基类就是解决多继承派生类对象存在基类的成员多分copy问题了,上面的代码改为
class Employee {//职工
public:
void pay()//支付月薪
{
cout<<"哎呀,employee,要发工资了"<<endl;
}
};
class Technical: virtual public Employee {//技术,也是职工
};
class Manager: virtual public Employee {//经理,也是职工
};
class TechnicalManager:public Technical,public Manager {//技术经理,也是职工
};
int main(int argc, const char * argv[])
{
TechnicalManager tManager;
tManager.pay();
return 0;
}
多态,即同样的消息被不同类型的对象接受时导致不同的行为,下面例子:
class Employee {
public:
void pay()
{
cout<<"哎呀,Employee,发工资了"<<endl;
}
};
class Technical: public Employee {
public:
void pay()
{
cout<<"哎呀,Technical,发工资了"<<endl;
}
};
class Manager: public Employee {
public:
void pay()
{
cout<<"哎呀,Manager,发工资了"<<endl;
}
};
void fun(Employee *ptr)
{
ptr->pay();
}
int main(int argc, const char * argv[])
{
Employee *pEmployee;
Technical technical;
pEmployee = &technical;
fun(pEmployee);
Manager manager;
pEmployee = &manager;
fun(pEmployee);
return 0;
}
终端输入结果:
哎呀,Employee,发工资了
哎呀,Employee,发工资了
,这不是大家想要的,这是多态吗?当然不是,这里的绑定是静态绑定,即编译时系统就根据类型匹配来确定程序中调用与执行的关系。
2。虚函数:c++支持多态主要就是靠虚函数,这事本文第二种“虚”,将上面的Employee 的pay方法前添加virtual,该函数就是虚函数了
class Employee {
public:
virtual void pay()
{
cout<<"哎呀,Employee,发工资了"<<endl;
}
};
终端输入结果:
哎呀,Technical,发工资了
哎呀,Manager,发工资了
呵呵,这下ok了吧,虚函数其实就是动态绑定,即在程序运行时才确定程序中调用与执行的关系
3。纯虚函数,最后一种虚
上面的代码中你会发现,Employee中的pay就没有用过,并且也不需要用到,因为你进入公司要么就是Technical(技术)要么就是TechnicalManager(技术经理),(假如你是搞技术的),Employee对公司所有的员工都适合,但是Employee中声明的pay函数目的只是为整个类族规定统一的对外接口功能,所以pay的实现就显得多余了,这样c++中就有了纯虚函数的概念,纯虚函数的格式就是该函数不给出实现,函数后面追加 “=0”,
如
class Employee {
public:
virtual void pay() = 0;
};
类中包含纯虚函数的类就是抽象类,抽象类不能够实例化,这些都符合我们对Employee的要求。