函数重载:
函数重载定义:
函数重载指的是在同一个类中定义多个具有相同名称但参数列表不同的函数。编译器根据调用时传递的参数数量或类型来选择正确的函数。函数重载通常用于实现相似但参数不同的操作。
函数重载的特征:
(1)作用的范围相同(定义在同一个类中);
(2)函数名字相同;
(3)参数个数、类型不同;
(4)返回值可以不同;
函数重载的代码样例:
#include <iostream>
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
};
int main() {
Calculator calc;
int sum1 = calc.add(5, 3); // 调用第一个add函数
double sum2 = calc.add(2.5, 3.7); // 调用第二个add函数
std::cout << "Sum1: " << sum1 << std::endl;
std::cout << "Sum2: " << sum2 << std::endl;
return 0;
}
在上面的示例中,Calculator
类中有两个名为 add
的函数,一个接受两个整数参数,另一个接受两个双精度浮点数参数,而且返回的数据类型不同,对应函数重载的四个特征,需要注意的是编译器是根据传递的参数类型来选择正确的函数。
函数重写:
函数重写定义:
函数重写(也叫函数覆盖override)是面向对象编程中的概念,它涉及到继承和虚函数。在子类中可以重新定义父类中的虚函数,以实现特定的行为。当然,子类中的重写函数的名称、返回类型和参数列表都必须与父类中的虚函数相匹配。
函数重写的特征:
(1)作用的范围不同(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有 virtual 关键字,不能有 static 。
(5)返回值相同,否则报错;
(6)重写函数的访问修饰符可以不同;
函数重写的代码样例:
#include <iostream>
class Shape {
public:
virtual void draw() {
std::cout << "Drawing a shape." << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle." << std::endl;
}
};
int main() {
Shape* shapePtr = new Circle();
shapePtr->draw(); // 调用了Circle类中的重写函数
delete shapePtr;
return 0;
}
在上面的示例中,Shape
类有一个虚函数 draw
,然后 Circle
类继承自 Shape
并重写了 draw
函数。在 main
函数中,我们创建了一个 Circle
对象的指针,但使用基类指针进行调用时,实际上调用了子类的重写函数。
虚函数:
虚函数概念:
在C++中,虚函数(Virtual Functions)是一种用于实现多态性(Polymorphism)的特殊类型的函数。虚函数使得你可以在基类(父类)和派生类(子类)之间建立一种特殊的联系,允许在运行时动态地选择要调用的函数版本,而不是在编译时确定。
关于虚函数的重要概念和用法:
基类和派生类:
虚函数通常用于面向对象编程中的继承体系。你会有一个基类(父类),然后从基类派生出一个或多个派生类(子类)。虚函数通常在基类中声明,然后可以在派生类中重写。
class Shape {
public:
virtual void draw() {
// 基类虚函数的默认实现
}
};
class Circle : public Shape {
public:
void draw() override {
// 派生类中的虚函数重写
}
};
声明虚函数:
在基类中,通过在函数声明前面加上 virtual
关键字来声明一个虚函数。虚函数可以有默认实现,也可以在基类中声明为纯虚函数(纯虚函数没有函数体,必须在派生类中实现)。
class Shape {
public:
virtual void draw(); // 声明一个虚函数
};
虚函数的重写:
在派生类中,可以使用 override
关键字来明确指示你要重写基类中的虚函数。重写的函数名称、参数列表和返回类型必须与基类中的虚函数匹配。
动态绑定:
当使用基类指针或引用来调用虚函数时,实际调用的是与指针或引用所指对象的类型相对应的派生类中的虚函数。这种动态选择要调用的函数版本称为动态绑定。
Shape* shapePtr = new Circle();
shapePtr->draw(); // 在运行时选择调用Circle类中的draw函数
虚析构函数:
如果一个类中使用了虚函数,通常也应该为它提供一个虚析构函数。这是因为在释放派生类对象时,如果不使用虚析构函数,可能会导致资源泄漏或未定义行为。
class Shape {
public:
virtual ~Shape() {} // 虚析构函数
};
虚函数使得C++能够实现运行时多态性,允许在不同的派生类中提供不同的实现,而且在使用基类指针或引用时,可以根据对象的实际类型来调用正确的函数版本。这种能力对于构建灵活且可扩展的程序非常有用。