C++ 虚函数
C++ 虚函数
在本教程中,我们将通过示例了解 C++ 虚函数及其使用。
虚函数是我们期望在派生类中重新定义的基类中的成员函数。
基本上,在基类中使用了一个虚函数,以确保该函数被覆盖 .这尤其适用于基类指针指向派生类对象的情况。
例如,考虑下面的代码:
class Base {
public:
void print() {
// code
}
};
class Derived : public Base {
public:
void print() {
// code
}
};
稍后,如果我们创建一个 Base
的指针 键入以指向 Derived
的对象 类并调用 print()
函数,它调用 print()
Base
的功能 类。
也就是说Base
的成员函数 没有被覆盖。
int main() {
Derived derived1;
Base* base1 = &derived1;
// calls function of Base class
base1->print();
return 0;
}
为了避免这种情况,我们声明 print()
Base
的功能 使用 virtual
作为虚拟类 关键字。
class Base {
public:
virtual void print() {
// code
}
};
虚函数是 C++ 中多态性的一个组成部分。要了解更多信息,请查看我们的 C++ 多态性教程。
示例1:C++虚函数
#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
在这里,我们声明了 print()
Base
的功能 作为 virtual
.
所以,即使我们使用 Base
的指针,这个函数也会被覆盖 指向 Derived
的类型 对象 derived1 .
C++ 覆盖标识符
C++ 11 给了我们一个新的标识符 override
这对于在使用虚函数时避免错误非常有用。
此标识符指定了覆盖基类成员函数的派生类的成员函数。
例如,
class Base {
public:
virtual void print() {
// code
}
};
class Derived : public Base {
public:
void print() override {
// code
}
};
如果我们在 Derived
中使用函数原型 类并在类之外定义该函数,然后我们使用以下代码:
class Derived : public Base {
public:
// function prototype
void print() override;
};
// function definition
void Derived::print() {
// code
}
使用 C++ 覆盖
使用虚函数时,在声明派生类的成员函数时可能会出错。
使用 override
出现这些错误时,标识符会提示编译器显示错误消息。
否则,程序只会编译,但不会覆盖虚函数。
其中一些可能的错误是:
- 名称不正确的函数: 例如,如果基类中的虚函数名为
print()
,但我们不小心将派生类中的覆盖函数命名为pint()
. - 具有不同返回类型的函数: 如果虚函数是
void
类型,但派生类中的函数是int
输入。 - 不同参数的函数: 如果虚函数的参数和派生类中的函数不匹配。
- 基类中没有声明虚函数。
C++ 虚函数的使用
假设我们有一个基类 Animal
和派生类Dog
和 Cat
.
假设每个类都有一个名为 type 的数据成员 .假设这些变量是通过各自的构造函数初始化的。
class Animal {
private:
string type;
... .. ...
public:
Animal(): type("Animal") {}
... .. ...
};
class Dog : public Animal {
private:
string type;
... .. ...
public:
Animal(): type("Dog") {}
... .. ...
};
class Cat : public Animal {
private:
string type;
... .. ...
public:
Animal(): type("Cat") {}
... .. ...
};
现在,让我们假设我们的程序需要我们创建两个 public
每个类的功能:
getType()
返回 type 的值print()
打印 type 的值
我们可以在每个类中分别创建这两个函数并覆盖它们,这将是漫长而乏味的。
或者我们可以制作 getType()
虚拟 在 Animal
类,然后创建一个单独的、单独的 print()
接受 Animal
指针的函数 类型作为它的参数。然后我们可以使用这个单一的函数来覆盖虚函数。
class Animal {
... .. ...
public:
... .. ...
virtual string getType {...}
};
... .. ...
... .. ...
void print(Animal* ani) {
cout << "Animal: " << ani->getType() << endl;
}
这将使代码更短 , 更干净 ,并且重复性较低 .
示例2:C++虚函数演示
// C++ program to demonstrate the use of virtual function
#include <iostream>
#include <string>
using namespace std;
class Animal {
private:
string type;
public:
// constructor to initialize type
Animal() : type("Animal") {}
// declare virtual function
virtual string getType() {
return type;
}
};
class Dog : public Animal {
private:
string type;
public:
// constructor to initialize type
Dog() : type("Dog") {}
string getType() override {
return type;
}
};
class Cat : public Animal {
private:
string type;
public:
// constructor to initialize type
Cat() : type("Cat") {}
string getType() override {
return type;
}
};
void print(Animal* ani) {
cout << "Animal: " << ani->getType() << endl;
}
int main() {
Animal* animal1 = new Animal();
Animal* dog1 = new Dog();
Animal* cat1 = new Cat();
print(animal1);
print(dog1);
print(cat1);
return 0;
}
输出
Animal: Animal Animal: Dog Animal: Cat
在这里,我们使用了虚函数 getType()
和一个 Animal
指针 ani 为了避免重复print()
在每个类中都起作用。
void print(Animal* ani) {
cout << "Animal: " << ani->getType() << endl;
}
在 main()
,我们创建了 3 个 Animal
动态创建 Animal
对象的指针 , Dog
和 Cat
类。
// dynamically create objects using Animal pointers
Animal* animal1 = new Animal();
Animal* dog1 = new Dog();
Animal* cat1 = new Cat();
然后我们调用 print()
使用这些指针的函数:
- 当
print(animal1)
被调用时,指针指向一个Animal
目的。所以,Animal
中的虚函数 类在print()
内部执行 . - 当
print(dog1)
被调用时,指针指向一个Dog
目的。所以,虚函数被覆盖,Dog
的函数 在print()
内执行 . - 当
print(cat1)
被调用,指针指向一个Cat
目的。所以,虚函数被覆盖,Cat
的函数 在print()
内部执行 .
C语言