C++——虛函數,純虛函數,函數重載

異質鏈表

虛函數
虛函數主要用于多態

若一個類中含有虛函數
則系統會自動的創建一個表,
該表用于存放虛函數的入口地址
稱該表為虛函數表

該類會自動添加一個指針,
該指針存放虛函數表的首地址
稱該指針為虛函數表指針

純虛函數
實現多態,實現沒有意義-->定義為純虛函數
含有純虛函數的類稱之為抽象類
抽象類不能定義對象

若派生類中,沒有對純虛函數進行定義
則該派生類仍為抽象類,不能定義對象

如果想用派生類生成對象,
則在派生類中必須要對純虛函數進行定義

若派生類中存在和基類虛函數函數原型相同的函數
則該派生類函數默認為虛函數

系統會自動的用該派生類函數的地址
覆蓋掉虛函數表中和其函數原型相同的基類的虛函數的地址

指針能夠訪問的范圍受類型局限
即只能訪問該指針類型中的成員
通過基類的指針或者引用來調用函數時
若該函數為虛函數,則到虛函數表中查找其入口地址
獲得地址后,轉到該地址執行函數

若派生類中存在和基類同名的成員變量
優先使用派生類中的成員變量

靜態聯邊和動態聯邊

靜態聯邊的對象是在編譯后確定(多態)
動態聯邊的對象是在運行時確定

在類中定義的普通函數默認為inline函數
(靜態成員函數,虛函數,構造函數,析構函數,不能為inline函數)
inline定義的內聯函數,函數代碼被放入符號表中,
在使用時進行替換(像宏一樣展開),效率很高。
類的內聯函數也是函數。編繹器在調用一個內聯函數,
首先會檢查參數問題,保證調用正確,
像對待真正函數一樣,消除了隱患及局限性。
inline可以作為類的成員函數,又可以使用所在類的保護成員及私有成員

#include <iostream>
#include <string>
using namespace std;

class Shape
{
public:
    //虛函數
    //虛函數主要用于多態

    //若一個類中含有虛函數
    //則系統會自動的創建一個表,
    //該表用于存放虛函數的入口地址
    //稱該表為虛函數表

    //該類會自動添加一個指針,
    //該指針存放虛函數表的首地址
    //稱該指針為虛函數表指針
    virtual float getArea()
    //float getArea()
    {
        return 0;
    }
};

class Rectangle: public Shape
{
public:
    Rectangle(float w = 0, float h = 0)
    {
        m_fWidth = w;
        m_fHeight = h;
    }
    //若派生類中存在和基類虛函數函數原型相同的函數
    //則該派生類函數默認為虛函數
    
    //系統會自動的用該派生類函數的地址
    //覆蓋掉虛函數表中和其函數原型相同的基類的虛函數的地址
    float getArea()
    {
        return m_fWidth * m_fHeight;
    }
    //類中定義的普通函數默認為inline函數
    //靜態成員函數,虛函數,構造函數,析構函數不能為inline
    //inline void test() 
    void test() 
    {}
private:
    float m_fWidth;
    float m_fHeight;
};

class Triangle: public Shape
{
public:
    Triangle(float b = 0, float h = 0)
    {
        m_fBottom = b;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fBottom * m_fHeight / 2;
    }
private:
    float m_fBottom;
    float m_fHeight;
};
#if 1
//指針能夠訪問的范圍受類型局限
//即只能訪問該指針類型中的成員
void fun(Shape *pShape)
{
    //通過基類的指針或者引用來調用函數時
    //若該函數為虛函數,則到虛函數表中查找其入口地址
    //獲得地址后,轉到該地址執行函數
    cout << pShape->getArea() << endl;
//  pShape->test();  //error
}
#endif

int main(void)
{
    cout << sizeof(Shape) << endl;
    Rectangle rec(3,4);
//  cout << rec.getArea() << endl;
    fun(&rec);  
    Triangle tri(3,4);
//  cout << tri.getArea() << endl;
    fun(&tri);
    Shape sh;
//  cout << sh.getArea() << endl;
    fun(&sh);
    return 0;
}
#include <iostream>
#include <string>
using namespace std;

class Shape
{
public:
    //純虛函數
    //實現多態,實現沒有意義--》定義為純虛函數
    //含有純虛函數的類稱之為抽象類
    //抽象類不能定義對象

    //若派生類中,沒有對純虛函數進行定義
    //則該派生類仍然為抽象類,不能定義對象

    //如果想用派生類生成對象,
    //則在派生類中必須對純虛函數進行定義
    virtual float getArea() = 0;
};

class Rectangle: public Shape
{
public:
    Rectangle(float w = 0, float h = 0)
    {
        m_fWidth = w;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fWidth * m_fHeight;
    }
private:
    float m_fWidth;
    float m_fHeight;
};

class Triangle: public Shape
{
public:
    Triangle(float b = 0, float h = 0)
    {
        m_fBottom = b;
        m_fHeight = h;
    }
    float getArea()
    {
        return m_fBottom * m_fHeight / 2;
    }
private:
    float m_fBottom;
    float m_fHeight;
};
void fun(Shape *pShape)
{
    cout << pShape->getArea() << endl;
}

int main(void)
{
    Rectangle rec(3,4);
    fun(&rec);  
    
    Triangle tri(3,4);
    fun(&tri);
    
    return 0;
}
#include <iostream>
#include <string>
using namespace std;

class Complex
{
public:
    Complex(int real = 0, int vir = 0)
    {
        m_iReal = real;
        m_iVir = vir;
    }
    void show()
    {
        cout << m_iReal << '+' << m_iVir << 'i' << endl;
    }
    friend Complex operator+(const Complex &c1
                             , const Complex &c2);
    friend Complex operator-(const Complex &c1
                             , const Complex &c2);
    friend bool operator>(const Complex &c1
                          , const Complex &c2);
private:
    int m_iReal;
    int m_iVir;
};

//返回值類型:Complex
//函數名:operator+
//形參列表:const Complex &c1, const Complex &c2
Complex operator+(const Complex &c1, const Complex &c2)
{
    Complex com;
    com.m_iReal = c1.m_iReal + c2.m_iReal;
    com.m_iVir = c1.m_iVir + c2.m_iVir;
    return com;
}
Complex operator-(const Complex &c1, const Complex &c2)
{
    Complex com;
    com.m_iReal = c1.m_iReal - c2.m_iReal;
    com.m_iVir = c1.m_iVir - c2.m_iVir;
    return com;
}

bool operator>(const Complex &c1, const Complex &c2)
{
    if (c1.m_iReal > c2.m_iReal 
        || ((c1.m_iReal == c2.m_iReal)
             &&(c1.m_iVir > c2.m_iVir)))
    {
        return true;
    }
    return false;
}

int main(void)
{
    Complex com(3, 4);
    com.show();

    Complex com2(4, 9);
    com2.show();

    //Complex com3 = com + com2;
    Complex com3 = operator+(com, com2);
    com3.show();
    
    //Complex com4 = com - com2;
    Complex com4 = operator-(com, com2);
    com4.show();

    if (com3 > com4)
    {
        cout << "com3 > com4" << endl;
    }
    else
    {
        cout << "com3 <= com4" << endl;
    }

    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,536評論 1 51
  • C++文件 例:從文件income. in中讀入收入直到文件結束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 2,850評論 0 3
  • C++虛函數 C++虛函數是多態性實現的重要方式,當某個虛函數通過指針或者引用調用時,編譯器產生的代碼直到運行時才...
    小白將閱讀 1,755評論 4 19
  • 1.面向對象的程序設計思想是什么? 答:把數據結構和對數據結構進行操作的方法封裝形成一個個的對象。 2.什么是類?...
    少帥yangjie閱讀 5,044評論 0 14
  • Introduction to C++ (Season 1) Unit 1: Overview of C++ 第1...
    我是阿喵醬閱讀 2,771評論 0 7