📜  C++ |虚函数|问题7(1)

📅  最后修改于: 2023-12-03 14:59:48.209000             🧑  作者: Mango

C++ 虚函数问题7

虚函数是C++的一个重要特性,它允许在基类中声明、而在派生类中重新定义的函数。

问题描述

在使用虚函数时,有一个常见的问题是在派生类中覆盖了父类的成员函数,但没有使用 virtual 关键字。例如:

#include <iostream>

class A {
public:
    virtual void foo() { std::cout << "A::foo()" << std::endl; }
};

class B : public A {
public:
    void foo() { std::cout << "B::foo()" << std::endl; }
};


int main() {
    A* p = new B();
    p->foo(); // 输出 "B::foo()"
    delete p;
    return 0;
}

这段代码中,派生类 B 中覆盖了基类 A 中的 foo() 函数,但是没有加上 virtual 关键字。我们在这里调用 p 对象的 foo() 函数,实际上调用的是 B 类中的 foo() 函数。为什么会这样呢?

问题原因

在 C++ 中,一个函数要能够被定义为虚函数,必须满足两个条件:

  1. 该函数必须是类的成员函数。
  2. 该函数必须在基类中以 virtual 关键字声明过。

如果一个函数在基类中被声明为虚函数,在派生类中重新定义时就不需要再次使用 virtual 关键字。这是因为,派生类中的成员函数如果与基类中的同名函数形成重载关系,那么编译器会在派生类中自动将该函数声明为虚函数,无需再使用 virtual 关键字。

所以,在上面的代码中,虽然 B 类中的 foo() 函数没有使用 virtual 关键字,但它实际上已经被自动声明为了一个虚函数。因此,在使用 p 对象指针调用 foo() 函数时,调用的是 B 类中的 foo() 函数。

总结

在使用虚函数时,一定要注意以下几点:

  1. 把虚函数的声明放在基类中。
  2. 不要在派生类中重载虚函数,而要覆盖它。
  3. 派生类中的覆盖函数不需要使用 virtual 关键字。
  4. 调用虚函数时,使用指向基类对象的指针或引用,可以实现多态性。