虚函数与多态

来源:互联网 发布:小码哥java培训怎么样 编辑:程序博客网 时间:2024/06/18 00:23
是否构成多态的条件:
1、父类的指针或引用
2、虚函数的重写
是否构成虚函数的条件:
1、有virtual
2、函数完全相同(协变:返回值可以不同,但返回值是父子关系的引用或指针)
#include <iostream>
using namespace std;
//基类
class Person
{
public:
virtual void BuyTickets()
{
cout << "买成人票" << endl;
}
};
//派生类
class Student:public Person
{
public:
virtual void BuyTickets()
{
cout << "买小孩票" << endl;
}
};
void Fun(Person& p)
{
p.BuyTickets();
}
//构成多态,和类型无关,和对象有关
void Test()
{
Person p;
Student s;
Fun(p);
Fun(s);
}
int main()
{
Test();
system("pause");
return 0;
}
输出:
买成人票
买小孩票
--------------------------------------------------------
去掉基类的virtual
#include <iostream>
using namespace std;
//基类
class Person
{
public:
void BuyTickets()//去掉virtual,构不成多态,就和类型有关,p是基类的就全部调的是基类
{
cout << "买成人票" << endl;
}
};
//派生类
class Student:public Person
{
public:
virtual void BuyTickets()
{
cout << "买小孩票" << endl;
}
};
输出:
买成人票
买成人票
------------------------------------------------------
去掉子类的virtual
#include <iostream>
using namespace std;
//基类
class Person
{
public:
virtual void BuyTickets()//
{
cout << "买成人票" << endl;
}
};
//派生类
class Student:public Person
{
public:
void BuyTickets()//只去掉子类的virtual,还是会构成多态,因为子类继承父类,输出和第一次一样
{
cout << "买小孩票" << endl;
}

};

这里总结一个基类和子类加不加virtual的效果:

基类

子类

效果

加virtual

virtual

构成多态,与对象有关

加virtual

不加virtual

构成多态,与对象有关

不加virtual

加virtual

不构成多态,与类型有关

不加virtual

不加virtual

不构成多态,与类型有关

也就是说主要看基类加不加virtual,如果基类加virtual则构成多态,效果和对象有关;如果基类不加virtual则不构成多态,效果和类型有关。

-----------------------------------------------
如果返回值不同:
父类为int,子类为void
class Person
{
public:
virtual int BuyTickets()//
{
cout << "买成人票" << endl;
}
};
//派生类
class Student:public Person
{
public:
virtual void BuyTickets()//
{
cout << "买小孩票" << endl;
}
};
会弹出一个错误:返回类型与重写虚拟函数 "Person::BuyTickets" 的返回类型 "int" 既不相同,也不协变
协变:当返回值不同,但返回值必须构成子类和父类的关系的指针或引用
协变的例子如下所示:
class Person
{
public:
virtual Person* BuyTickets()//
{
cout << "买成人票" << endl;
return this;
}
};
//派生类
class Student:public Person
{
public:
virtual Student*BuyTickets()//
{
cout << "买小孩票" << endl;
return this;
}
};
这里的Person* 和Student*不一定必须是这俩,只要能构成父子关系即可。
原创粉丝点击