多态是面向对象编程的一个重要概念。它简单地意味着一种以上的形式。也就是说,相同的实体(函数或运算符)在不同的场景下表现不同。例如,
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++ 中,如果我们有两个同名函数但参数不同(类型或数量不同),这是允许的。
并且,根据传递的参数的数量/类型,会调用不同的函数。例如,
// C++ program to overload sum() function
#include <iostream>
using namespace std;
// Function with 2 int parameters
int sum(int num1, int num2) {
return num1 + num2;
}
// Function with 2 double parameters
double sum(double num1, double num2) {
return num1 + num2;
}
// Function with 3 int parameters
int sum(int num1, int num2, int num3) {
return num1 + num2 + num3;
}
int main() {
// Call function with 2 int parameters
cout << "Sum 1 = " << sum(5, 6) << endl;
// Call function with 2 double parameters
cout << "Sum 2 = " << sum(5.5, 6.6) << endl;
// Call function with 3 int parameters
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++ program to overload ++ when used as prefix
#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 变量直接增加 1
。
这也是编译时多态。
要了解更多信息,请访问我们的C++ 运算符重载教程。
C++ 函数重写
在C++ 继承中,基类及其派生类中可以有同名函数。
当使用派生类对象调用函数时,会执行派生类的函数,而不是基类的函数。
因此,根据调用函数的对象,会执行不同的函数。
这就是 C++ 中的函数覆盖。例如,
// C++ program to demonstrate function overriding
#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
在这里,我们在 Base
类中使用了 print()
函数,并在 Derived
类中使用了相同的函数。
当使用 Derived
对象 derived1 调用 print()
时,它会通过执行 Derived
类的 print()
函数来覆盖 Base
的 print()
函数。
这是运行时多态,因为函数调用不是由编译器解析的,而是在运行时解析的。
要了解更多信息,请访问我们的C++ 函数覆盖教程。
C++ 虚函数
在 C++ 中,如果我们使用基类指针指向派生类对象,我们可能无法覆盖函数。
在基类中使用虚函数可以确保在这些情况下函数可以被覆盖。
因此,虚函数实际上属于函数覆盖。例如,
// C++ program to demonstrate the use of virtual functions
#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()
比创建不同名称的函数更有意义,从而使我们的代码更加一致。