C++ 多态性
在本教程中,我们将借助示例了解 C++ 中的多态性。
多态是面向对象编程的一个重要概念。它只是意味着不止一种形式。也就是说,相同的实体(函数或运算符)在不同的场景中表现不同。例如,
C++ 中的 +
运算符用于执行两个特定的功能。当它与数字(整数和浮点数)一起使用时,它执行加法。
int a = 5;
int b = 6;
int sum = a + b; // sum = 11
当我们将 +
运算符与字符串一起使用时,它会执行字符串连接。例如,
string firstName = "abc ";
string lastName = "xyz";
// name = "abc xyz"
string name = firstName + lastName;
C++ 中的多态性主要体现在以下几个方面:
C++ 函数重载
在 C++ 中,我们可以使用两个具有相同名称的并且具有不同的参数(类型或参数数量)函数。
并且,根据参数的数量/类型,调用不同的函数。例如,
#include <iostream>
using namespace std;
// 两个 int 类型的参数
int sum(int num1, int num2) {
return num1 + num2;
}
// 两个 double 类型的参数
double sum(double num1, double num2) {
return num1 + num2;
}
// 三个 int 类型的参数
int sum(int num1, int num2, int num3) {
return num1 + num2 + num3;
}
int main() {
cout << "Sum 1 = " << sum(5, 6) << endl;
cout << "Sum 2 = " << sum(5.5, 6.6) << endl;
cout << "Sum 3 = " << sum(5, 6, 7) << endl;
return 0;
}
输出
Sum 1 = 11
Sum 2 = 12.1
Sum 3 = 18
在这里,我们创建了 3 个具有不同参数(参数数量/类型)的 sum()
函数。并且,根据函数调用期间传递的参数,确定调用的是哪一个 sum()
函数。
这是一种编译时多态性,因为编译器在编译程序之前就知道要执行哪个函数。
要了解更多信息,请访问我们的C++ 函数重载教程。
C++ 运算符重载
在 C++ 中,只要我们对用户定义的类型(如对象或结构)进行操作,就可以重载运算符。
我们不能将运算符重载用于基本类型,例如 int
, double
等。
运算符重载本质上是函数重载,其中不同的运算符函数具有相同的符号但操作数不同。
并且,根据操作数,执行不同的运算符函数。例如,
C++ 程序重载 ++
前缀:
#include <iostream>
using namespace std;
class Count {
private:
int value;
public:
// Constructor to initialize count to 5
Count() : value(5) {}
// Overload ++ when used as prefix
void operator ++() {
value = value + 1;
}
void display() {
cout << "Count: " << value << endl;
}
};
int main() {
Count count1;
// Call the "void operator ++()" function
++count1;
count1.display();
return 0;
}
输出
Count: 6
在这里,我们重载了 ++
操作符,它对 Count
类的对象(本例中的 count1
)。
我们使用了这个重载的运算符来直接 count1
对象的成员变量 value
。
这也是一种编译时多态性。
要了解更多信息,请访问我们的C++ 运算符重载教程。
C++ 函数覆盖
在C++ 继承中,我们可以在基类及其派生类中拥有相同的功能。
当我们使用派生类的对象调用函数时,会执行派生类的函数而不是基类中的函数。
因此,根据调用函数的对象执行不同的函数。
这在 C++ 中称为函数覆盖。例如,
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base Function" << endl;
}
};
class Derived : public Base {
public:
void print() {
cout << "Derived Function" << endl;
}
};
int main() {
Derived derived1;
// Call print() function of Derived class
derived1.print();
return 0;
}
输出
Derived Function
在这里,我们使用了 Derived
类中的一个 print()
函数,它覆盖了类 Base
中的 print()
函数。
当我们使用 Derived
对象 derived1
调用 print()
时,它通过执行 Derived
类的 print()
函数来覆盖 Base
中的函数。
这是一个运行时多态性,因为函数调用不是由编译器解析的,而是在运行时解析的。
要了解更多信息,请访问我们的C++ 函数覆盖教程。
C++ 虚函数
在 C++ 中,如果我们使用基类的指针指向派生类的对象,我们可能无法覆盖函数。
在基类中使用虚函数可确保在这些情况下可以覆盖函数。
因此,虚函数实际上属于函数覆盖。例如,
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base Function" << endl;
}
};
class Derived : public Base {
public:
void print() {
cout << "Derived Function" << endl;
}
};
int main() {
Derived derived1;
// pointer of Base type that points to derived1
Base* base1 = &derived1;
// calls member function of Derived class
base1->print();
return 0;
}
输出
Derived Function
在这里,我们在 Base
类中使用了一个虚函数 print()
来确保它被 Derived
类中的函数覆盖。
虚函数是运行时多态性。
要了解更多信息,请访问我们的C++ 虚拟函数教程。
为什么是多态性?
多态性允许我们创建一致的代码。例如,
假设我们需要计算一个圆和一个正方形的面积。为此,我们可以创建一个 Shape
类并从中派生两个类 Circle
和 Square
。
在这种情况下,在两个派生类中创建一个具有相同名称的函数 calculateArea()
而不是创建具有不同名称的函数是有意义的,从而使我们的代码更加一致。