解析C++编程中virtual声明的虚函数以及单个继承

2020-01-06 14:23:48于丽

以下示例说明在通过指针调用时虚函数和非虚函数的行为:


// deriv_VirtualFunctions2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

class Base {
public:
  virtual void NameOf();  // Virtual function.
  void InvokingClass();  // Nonvirtual function.
};

// Implement the two functions.
void Base::NameOf() {
  cout << "Base::NameOfn";
}

void Base::InvokingClass() {
  cout << "Invoked by Basen";
}

class Derived : public Base {
public:
  void NameOf();  // Virtual function.
  void InvokingClass();  // Nonvirtual function.
};

// Implement the two functions.
void Derived::NameOf() {
  cout << "Derived::NameOfn";
}

void Derived::InvokingClass() {
  cout << "Invoked by Derivedn";
}

int main() {
  // Declare an object of type Derived.
  Derived aDerived;

  // Declare two pointers, one of type Derived * and the other
  // of type Base *, and initialize them to point to aDerived.
  Derived *pDerived = &aDerived;
  Base  *pBase  = &aDerived;

  // Call the functions.
  pBase->NameOf();      // Call virtual function.
  pBase->InvokingClass();  // Call nonvirtual function.
  pDerived->NameOf();    // Call virtual function.
  pDerived->InvokingClass(); // Call nonvirtual function.
}

输出


Derived::NameOf
Invoked by Base
Derived::NameOf
Invoked by Derived

请注意,无论 NameOf 函数是通过指向 Base 的指针还是通过指向 Derived 的指针进行调用,它都会调用 Derived 的函数。 它调用 Derived 的函数,因为 NameOf 是虚函数,并且 pBase 和 pDerived 都指向类型 Derived 的对象。
由于仅为类类型的对象调用虚函数,因此不能将全局函数或静态函数声明为 virtual。
在派生类中声明重写函数时可使用 virtual 关键字,但它不是必需的;虚函数的重写始终是虚拟的。
必须定义基类中的虚函数,除非使用 pure-specifier 声明它们。 (有关纯虚函数的详细信息,请参阅抽象类。)
可通过使用范围解析运算符 (::) 显式限定函数名称来禁用虚函数调用机制。 考虑先前涉及 Account 类的示例。 若要调用基类中的 PrintBalance,请使用如下所示的代码:


CheckingAccount *pChecking = new CheckingAccount( 100.00 );

pChecking->Account::PrintBalance(); // Explicit qualification.

Account *pAccount = pChecking; // Call Account::PrintBalance

pAccount->Account::PrintBalance();  // Explicit qualification.

在前面的示例中,对 PrintBalance 的调用将禁用虚函数调用机制。


单个继承
在“单继承”(继承的常见形式)中,类仅具有一个基类。考虑下图中阐释的关系。