C++多态的定义以及实现

0 阅读3分钟

多态是一个继承关系下的类对象,去调用同一个函数,产生了不同行为。比如所Student继承了Person.Person对象买票全价格,Student对象优惠买票。

实现多态的两个条件 必须是基类的指针或者引用调用虚函数 被调用的函数必须是虚函数,并且完成了虚函数的重写/覆盖。

要实现多态的效果有两个重要的点:

必须的是基类的指针或者引用做参数,因为只有基类的指针或者引用才能既指向基类对象又指向派生类对象。 派生类对象必须对基类的虚函数完成重写/覆盖,重写或者覆盖了,基类和派生类之间才能有不同的函数,多态的效果才能达到。 虚函数 类成员前面加virtual修饰,那么这个成员函数被称为虚函数。注意非成员函数不能加virtual修饰。

class Animal { public: virtual void speak() const { // 正确:成员虚函数 cout << "动物在叫:" << endl; } }; class Dog : public Animal {//派生类 public: virtual void speak() const { // 重写虚函数,加virtual修饰 cout << "汪汪汪!" << endl; } }; class Cat : public Animal {//派生类 public: virtual void speak() const { // 重写虚函数 cout << "喵喵喵!" << endl; } }; //非成员函数不能加 virtual,会出现编译错误 //virtual void printHello() {
// cout << "Hello" << endl; //}

void letsHear(const Animal& animal) { animal.speak(); }

int main() { Cat cat; Dog dog; letsHear(cat); letsHear(dog); return 0; }

虚函数的重写/覆盖 虚函数的重写/覆盖:派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称派生类的虚函数重写了基类的虚函数。

class Person { public: virtual void BuyTicket() { cout << "买票全价" << endl; } }; class Student :public Person { virtual void BuyTicket() { cout << "买票半价" << endl; } }; void Func(Person* ptr) { //这里可以看到虽然都是Person指针在调用BuyTicket //这个东西本质上是与ptr指向的对象有关 ptr->BuyTicket(); } int main() { Person ZhangSan; Func(&ZhangSan);

Student WangWu;
Func(&WangWu);

return 0;

}

需要注意的是:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类中依旧保持虚函数属性)这样的写法是不规范的,不建议这样使用。但是在考题中,经常会故意埋个坑,让你判断是否构成多态。

多态场景下的一个小测试 下列程序的输出结果是什么?( ) A.A->0 B.B->1 C:A->1 D:B->0 E:编译出错 F:以上都不正确

class A { public: virtual void func(int val = 1) { cout << "A->" << val << endl; } virtual void text(int val = 1) { func(); } }; class B :public A { public: void func(int val = 0){ cout << "B->" << val << endl; } }; int main(int argc,char* argv[]) { B* p = new B; p->text(); return 0; }

派生类类的指针调用text,将B*的this 指针传递给text,基类和派生类中的两个func()函数构成多态,所以这里的func()调用的是B类中的func。最最关键的在于,构成重写的两个虚函数,重写的是虚函数的实现,所以实际上val的值为1,用的B中func。答案选B。 ————————————————