跳到主要内容

C++ 函数重写

提示
  1. 函数覆盖定义:在C++中,如果派生类和基类都定义了同名函数,使用派生类对象调用该函数时,将执行派生类中的函数,这被称为函数覆盖。
  2. 访问被覆盖的基类函数:可以使用作用域解析运算符::访问被派生类覆盖的基类函数。例如,derived2.Base::print();将调用基类的print()函数。
  3. 使用指针访问函数:通过基类类型的指针指向派生类对象,调用函数时将执行基类中的函数,而不是被覆盖的派生类函数。若基类中的函数被声明为虚函数,则可实现函数的覆盖。

正如我们所知,继承是面向对象编程中的一个特性,它允许我们从基类创建派生类。派生类继承了基类的特性。

假设,相同的函数在派生类和基类中都被定义了。现在如果我们使用派生类的对象调用这个函数,将执行派生类中的函数。

这在C++中被称为函数覆盖。派生类中的函数覆盖了基类中的函数。

示例 1:C++ 函数覆盖

// C++ 程序演示函数覆盖

#include <iostream>
using namespace std;

class Base {
public:
void print() {
cout << "基类函数" << endl;
}
};

class Derived : public Base {
public:
void print() {
cout << "派生类函数" << endl;
}
};

int main() {
Derived derived1;
derived1.print();
return 0;
}

输出

派生类函数

这里,相同的函数 print()BaseDerived 类中都被定义了。

所以,当我们从 Derived 对象 derived1 调用 print() 时,通过覆盖 Base 中的函数执行了 Derived 中的 print()

C++ 函数覆盖的工作原理

我们可以看到,函数被覆盖了,因为我们是从 Derived 类的对象调用的函数。

如果我们从 Base 类的对象调用了 print() 函数,函数就不会被覆盖。

// 调用 Base 类的函数
Base base1;
base1.print(); // 输出:基类函数

C++ 访问被覆盖的函数

要访问基类中被覆盖的函数,我们使用作用域解析运算符 ::

我们还可以使用指向基类的指针指向派生类的对象,然后通过该指针调用函数。

示例 2:C++ 访问基类中被覆盖的函数

// C++ 程序在 main() 中使用作用域解析运算符 :: 访问被覆盖的函数

#include <iostream>
using namespace std;

class Base {
public:
void print() {
cout << "基类函数" << endl;
}
};

class Derived : public Base {
public:
void print() {
cout << "派生类函数" << endl;
}
};

int main() {
Derived derived1, derived2;
derived1.print();

// 访问 Base 类的 print() 函数
derived2.Base::print();

return 0;
}

输出

派生类函数
基类函数

这里,这个语句

derived2.Base::print();

访问了 Base 类的 print() 函数。

C++ 使用派生对象访问被覆盖的函数

示例 3:C++ 在派生类中调用被覆盖的函数

// C++ 程序在派生类的成员函数中调用被覆盖的函数

#include <iostream>
using namespace std;

class Base {
public:
void print() {
cout << "基类函数" << endl;
}
};

class Derived : public Base {
public:
void print() {
cout << "派生类函数" << endl;

// 调用被覆盖的函数
Base::print();
}
};

int main() {
Derived derived1;
derived1.print();
return 0;
}

输出

派生类函数
基类函数

在这个程序中,我们在 Derived 类内部调用了被覆盖的函数。

class Derived : public Base {
public:
void print() {
cout << "派生类函数" << endl;
Base::print();
}
};

注意代码 Base::print();,它在 Derived 类中调用了被覆盖的函数。

C++ 在派生类内部访问被覆盖的函数

示例 4:C++ 使用指针调用被覆盖的函数

// C++ 程序使用指向 Base 类型的指针指向 Derived 类的对象来访问被覆盖的函数

#include <iostream>
using namespace std;

class Base {
public:
void print() {
cout << "基类函数" << endl;
}
};

class Derived : public Base {
public:
void print() {
cout << "派生类函数" << endl;
}
};

int main() {
Derived derived1;

// 指向 derived1 的 Base 类型的指针
Base* ptr = &derived1;

// 使用 ptr 调用 Base 类的函数
ptr->print();

return 0;
}

输出

基类函数

在这个程序中,我们创建了一个名为 ptr 的 Base 类型的指针。这个指针指向 Derived 对象 derived1。

// 指向 derived1 的 Base 类型的指针
Base* ptr = &derived1;

当我们使用 ptr 调用 print() 函数时,它调用了 Base 中的被覆盖函数。

// 使用 ptr 调用 Base 类的函数
ptr->print();

这是因为即使 ptr 指向 Derived 对象,它实际上是 Base 类型的。所以,它调用了 Base 的成员函数。

为了覆盖 Base 函数而不是访问它,我们需要在 Base 类中使用虚函数