您好,登錄后才能下訂單哦!
本篇內容主要講解“C++中虛函數介紹及其作用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++中虛函數介紹及其作用”吧!
概述
使用方法
關聯
靜態關聯
動態關聯
案例1
未使用虛函數
使用虛擬類
案例2
總結
虛函數 (virtual function) 指可以被子類繼承和覆蓋的函數.
基類聲明成員函數為虛函數的方法:
virtual [類型] 函數名([參數表列])
注: 在類外定義虛函數時, 不需再加 virtual.
虛函數的特點:
提高程序擴充性: 派生類根據需要可以進行函數覆蓋
成員函數被聲明為虛數后, 其派生類中覆蓋函數自動稱為虛函數
若虛函數在派生類中未重新定義, 則派生類簡單繼承其直接基類的虛函數
指向基類的指針, 當指向派生類對象時, 可以嗲用派生類的方法
通過關聯 (binding), 我們可以把一個標識符和一個存儲地址聯系起來, 或者把一個函數名與一個類對象捆綁在一起.
靜態關聯 (static binding) 指通過對象名調用虛函數. 在編譯時即可確定其調用的虛函數屬于哪一類
動態關聯 (dynamic binding) 是指通過基類指針與虛函數, 在運行階段確定關聯關系. 動態關聯提供動態的多態性, 即運行階段的多態性.
Square 類:
#ifndef PROJECT6_SQUARE_H #define PROJECT6_SQUARE_H class Square { protected: int length; public: Square(int l) : length(l) {}; int area() const { return length *length; } }; #endif //PROJECT6_SQUARE_H
Rectangle 類:
#ifndef PROJECT6_RECTANGLE_H #define PROJECT6_RECTANGLE_H #include "Square.h" class Rectangle : public Square{ private: int height; public: Rectangle(int l, int h) : Square(l), height(h) {}; int area() const { return Square::area() * 2 + length * height * 4; // 兩個底加四個邊 } }; #endif //PROJECT6_RECTANGLE_H
main:
#include <iostream> #include "Square.h" #include "Rectangle.h" using namespace std; int main() { // 創建對象 Square s1(2), *pt; Rectangle r1(3, 3); pt = &s1; cout << pt->area() << endl; pt = &r1; cout << pt->area() << endl; return 0; }
輸出結果:
4
9 // 輸出的是底面積
此時調用的是 Square 類的area()
函數.
Square 類:
#ifndef PROJECT6_SQUARE_H #define PROJECT6_SQUARE_H class Square { protected: int length; public: Square(int l) : length(l) {}; virtual int area() const { return length *length; } }; #endif //PROJECT6_SQUARE_H
Rectangle 類:
#ifndef PROJECT6_RECTANGLE_H #define PROJECT6_RECTANGLE_H #include "Square.h" class Rectangle : public Square{ private: int height; public: Rectangle(int l, int h) : Square(l), height(h) {}; int area() const { return Square::area() * 2 + length * height * 4; // 兩個底加四個邊 } }; #endif //PROJECT6_RECTANGLE_H
main:
#include <iostream> #include "Square.h" #include "Rectangle.h" using namespace std; int main() { // 創建對象 Square s1(2), *pt; Rectangle r1(3, 3); pt = &s1; cout << pt->area() << endl; pt = &r1; cout << pt->area() << endl; return 0; }
輸出結果:
4
54 // 長方體的面積
此時調用的是 Rectangle 類的area()
函數.
Animal 類:
#ifndef PROJECT6_ANIMAL_H #define PROJECT6_ANIMAL_H #include <iostream> using namespace std; class Animal { public: virtual void bark(){ cout << "咋叫?" << endl; } }; #endif //PROJECT6_ANIMAL_H
Dog 類:
#ifndef PROJECT6_DOG_H #define PROJECT6_DOG_H #include "Animal.h" class Dog : public Animal{ public: void bark() { cout << "汪汪!" << endl; } }; #endif //PROJECT6_DOG_H
Cat 類:
#ifndef PROJECT6_CAT_H #define PROJECT6_CAT_H #include "Animal.h" class Cat : public Animal{ public: void bark() { cout << "喵喵!" << endl; } }; #endif //PROJECT6_CAT_H
Pig 類:
#ifndef PROJECT6_PIG_H #define PROJECT6_PIG_H #include "Animal.h" class Pig : public Animal { public: void bark() { cout << "哼哼!" << endl; } }; #endif //PROJECT6_PIG_H
main:
#include <iostream> #include "Animal.h" #include "Dog.h" #include "Cat.h" #include "Pig.h" using namespace std; int main() { // 創建對象 Animal a, *pt; Dog d; Cat c; Pig p; pt = &a; pt -> bark(); // 調用基類的bark() pt = &d; pt -> bark(); // 調用狗的bark() pt = &c; pt -> bark(); // 調用貓的bark() pt = &p; pt -> bark(); // 調用豬的bark() return 0; }
輸出結果:
咋叫?
汪汪!
喵喵!
哼哼!
虛函數只能是類的成員函數, 而不能將類外的普通函數聲明為虛函數. 虛函數的作用是允許在派生類中對基類的虛函數重新定義 (函數覆蓋), 只能用于類的繼承層次結構中.
虛函數能有效減少空間開銷. 當一個類帶有虛函數時, 編譯系統會為該類構造一個虛函數表 (一個指針數組), 用于存放每個虛函數的入口地址.
什么時候應該使用虛函數:
判斷成員函數所在的類是不是基類, 非基類無需使用虛函數
成員函數在類被繼承后有沒有可能被更改的功能, 如果希望修改成員函數功能, 一般在基類中將其聲明為虛函數
我們會通過對象名還是基類指針訪問成員函數, 如果通過基類指針過引用去訪問, 則應當聲明為虛函數
有時候在定義虛函數的時候, 我們無需定義其函數體. 它的作用只是定義了一個虛函數名, 具體的功能留給派生類去添加, 也就是純虛函數. 例如我們在上面的 Animal 類的bark()
函數就應該聲明為純虛函數, 因為 Animal 為基類, 定義bark()
函數實體并無意義.
到此,相信大家對“C++中虛函數介紹及其作用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。