亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

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 出现这些错误时,标识符会提示编译器显示错误消息。

否则,程序只会编译,但不会覆盖虚函数。

其中一些可能的错误是:


C++ 虚函数的使用

假设我们有一个基类 Animal 和派生类DogCat .

假设每个类都有一个名为 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 每个类的功能:

  1. getType() 返回 type 的值
  2. 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 对象的指针 , DogCat 类。

// dynamically create objects using Animal pointers
Animal* animal1 = new Animal();
Animal* dog1 = new Dog();
Animal* cat1 = new Cat();

然后我们调用 print() 使用这些指针的函数:

  1. print(animal1) 被调用时,指针指向一个 Animal 目的。所以,Animal中的虚函数 类在 print() 内部执行 .
  2. print(dog1) 被调用时,指针指向一个Dog 目的。所以,虚函数被覆盖,Dog的函数 在 print() 内执行 .
  3. print(cat1) 被调用,指针指向一个Cat 目的。所以,虚函数被覆盖,Cat的函数 在 print() 内部执行 .

C语言

  1. 在 C++ 编程中将数组传递给函数
  2. C++ 类和对象
  3. C++朋友函数和朋友类
  4. C++ 类模板
  5. 带有程序示例的 C++ 函数
  6. Verilog 函数
  7. C - 函数
  8. C++ 中的存储类
  9. C++ 重载(运算符和函数)
  10. C++中的多态性
  11. C++ 中的数据抽象
  12. C++ 中的数据封装