文章目录
前言
在上一篇文章中,我们对C++的继承进行了详细的讲解,不知道大家掌握的怎么样呢,在这篇文章中我们将要对C++的多态进行详细的讲解,多态是在继承的前提下产生的,也是十分重要的内容,下面我们一起来看看吧。
补充:
在这里需要先声明一下,本文章的代码和解释都是在vs2019下的x86程序中,设计的指针都是4bytes,在其他的平台下,可能部分的代码需要改动,比如x64程序,需要考虑指针是8bytes问题等等
一、多态的概念
概念
**多态的概念:**通俗的来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
举个栗子
举一个很贴近我们生活的例子,比如说买票的这个行为,当普通人买票时,是全价买票,学生买票时,是半价买票,军人买票时是优先买票。这就构成了一个多态。
二、多态的定义及实现
1.多态的构成条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person,Soldier继承了Person。Person对象买票全价,Student对象买票半价,军人优先买票。
在继承中要构成多态还要有两个条件:
1.必须通过基类的指针或者引用调用虚函数
2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
总结:
就是以下两句话
多态的两个条件:
1.虚函数重写(这里本身就指定了必须是虚函数)
2.父类指针或者引用去调用虚函数
class Person
{
public:
virtual void BuyTicket()
{
cout << "买票-全价" << endl;
}
};
class Student :public Person
{
public:
virtual void BuyTicket()
{
cout << "买票-半价" << endl;
}
};
class Soldier :public Person
{
public:
virtual void BuyTicket()
{
cout << "优先买票" << endl;
}
};
void Func(Person& p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Student st;
Soldier sd;
Func(ps);
Func(st);
Func(sd);
return 0;
}

看输出结果。

这里我们可以看以不同的类对象去调用同一个函数会出现不同的状态,这个现象就是多态,是不是很神奇。
2.虚函数
虚函数: 即被virtual修饰的类成员函数称为虚函数。
在上面的例子中,我们看到了在讲述继承的时候出现的一个关键字,virtual,但是我们需要注意的是这两个地方的virtual是不同的,大家一定要区分开。
class Person
{
public:
//这里的BuyTicket就是虚函数
virtual void BuyTicket()
{
cout << "买票-全价" << endl;
}
};
3.虚函数的重写
虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。
class Person
{
public:
virtual void BuyTicket()
{
cout << "买票-全价" << endl;
}
};
class Student :public Person
{
public:
virtual void BuyTicket()
{
cout << "买票-半价" << endl;
}
//特例1:在重写基类函数时,子类虚函数不加 virtual时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用。
//void BuyTicket()
//{
// cout << "买票-半价" << endl;
//}
};
class Soldier :public Person
{
public:
virtual void BuyTicket()
{
cout << "优先买票" << endl;
}
};
//多态的两个条件
//1.虚函数重写
//2.父类指针或者引用去调用虚函数
void Func(Person& p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Student st;
Soldier sd;
Func(ps);
Func(st);
Func(sd);
return 0;
}
既然我们已经知道了构成的多态的条件,下面我们就来探究一下。我们来看一下修改其中的几个条件,是否还能构成的多态。
3.1多态条件探究
(1)多态条件探究一:不符合重写 – virtual函数
下面我们将virtual关键字去掉,看看是否能构成多态。
class Person
{
public:
void BuyTicket()
{
cout << "买票-全价" << endl;
}
};
class Student :public Person
{
public:
void BuyTicket()
{
cout << "买票-半价" << endl;
}
};
class Soldier :public Person
{
public:
void BuyTicket()
{
cout << "优先买票" << endl;
}
};
void Func(Person& p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Student st;
Soldier sd;
Func(ps);
Func(st);
Func(sd);
return 0;
}

通过输出结果我们可以看到这里是没有构成多态的。
(2)多态条件探究二:不符合重写 – 不是父类的指针或者引用调用
class Person
{
public:
virtual void BuyTicket()
{
cout << "买票-全价" << endl;
}
};
class Student :public Person
{
public:
virtual void BuyTicket()
{
cout << "买票-半价" << endl;
}
};
class Soldier :public Person
{
public:
virtual void BuyTicket()
{
cout << "优先买票" << endl;
}
};
void Func(Person p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Student st;
Soldier sd;
Func(ps);
Func(st);
Func(sd);
return 0;
}
看上面的代码,我们可以看到去掉的条件是:不是父类的指针或者引用调用,再看下面的输出结果。

这里也是不能构成多态的。
(3)多态条件探究三:不符合重写 – 参数不同
//(3)多态条件探究三:不符合重写 -- 参数不同
class Person
{
public:
virtual void BuyTicket(int)
{
cout << "买票-全价" << endl;
}
};
class Student :public Person
{
public:
//Student中函数的参数类型与父类不同
virtual void BuyTicket(char)
{
cout << "买票-半价" << endl;
}
};
class Soldier :public Person
{
public:
//Soldier中函数的参数类型与父类相同
virtual void
本文深入探讨了C++中的多态性,包括多态的概念、实现方式、构成条件、虚函数、重写规则、抽象类、多态原理以及析构函数的特殊性。通过实例代码解析了多态行为的产生,强调了虚函数表在多态中的作用,同时介绍了C++11的`override`和`final`关键字。文章还涉及了多态性与静态绑定的区别以及菱形继承等高级主题。
最低0.47元/天 解锁文章
831

被折叠的 条评论
为什么被折叠?



