C++虛函數(shù)和多態(tài)超詳細分析

1.什么是虛函數(shù)
C++類中用virtual修飾的函數(shù)叫做虛函數(shù),構造函數(shù)沒有虛構造函數(shù),存在虛析構函數(shù),C++所有虛函數(shù)都是一個指針去存儲的,所以具有虛函數(shù)的類,內(nèi)存會增加一個指針大小的內(nèi)存
#include<iostream>
#include<string>
using namespace std;
class MM
{
public:
//虛函數(shù)指針是同一個,所以無論該類中有多少個虛函數(shù),
//占用的內(nèi)存就只是一個指針的大小
virtual void print()
{
cout << "我是第一個虛函數(shù)" << endl;
}
virtual void printData()
{
cout << "我是第二個虛函數(shù)" << endl;
}
protected:
};
class son:public MM
{
public:
void print()
{
//該函數(shù)也是虛函數(shù),
//父類中同名函數(shù)是虛函數(shù)
//所以子類該函數(shù)也是虛函數(shù)
}
protected:
};
int main()
{
cout << sizeof(MM) << endl;
cout << "...................." << endl;
//虛函數(shù)表的理解,下面帶圖解
MM mm;
long long** p = (long long**)&mm;
using Func = void(*)();
Func f1 = (Func)p[0][0];
Func f2 = (Func)p[0][1];
f1();
f2();
return 0;
}

2.純虛函數(shù)
純虛函數(shù)也是虛函數(shù)的一種,只是沒有函數(shù)體,下面請看怎么表示沒有函數(shù)體
純虛函數(shù)——>虛函數(shù)=0;
具有一個或者多個虛函數(shù)的類叫做抽象類
- 抽象類不能構建對象
- 但是可以構建函數(shù)指針
#include<iostream>
using namespace std;
class MM
{
public:
virtual void print() = 0;
};
int main()
{
//MM mm; //抽象類不能構建對象
MM* pmm = nullptr;
return 0;
}
3.c++多態(tài)
多態(tài)指的是因為指針的不同的賦值操作所導致的同一行為的不同結果。多態(tài)的這個概念東西不太重要,重要的是什么樣的情況調(diào)用什么樣的行為
- 正常指針和正常對象調(diào)用行為,就近原則
- 父類指針被子類對象初始化
- 函數(shù)有
virtual看對象類型 - 函數(shù)沒有
virtual看指針類型 final關鍵字 禁止子類重寫父類方法override顯示說明當前函數(shù)是重寫函數(shù)
多態(tài)三個必要性條件:
- 父類中存在虛函數(shù)
- 存在不正常指針的引用(不正常賦值關系)
public繼承
#include<iostream>
using namespace std;
class MM
{
public:
void print()
{
cout << "父類" << endl;
}
virtual void printData()
{
cout << "MM" << endl;
}
};
class son :public MM
{
public:
void print()
{
cout << "子類" << endl;
}
void printData()
{
cout << "son" << endl;
}
};
int main()
{
MM* pmm = new son;
pmm->print();
pmm->printData();
return 0;
}
4.純虛函數(shù)和ADT過程
ADT:abstract data type抽象數(shù)據(jù)類型,主要是通過繼承抽象類中,子類必須要實現(xiàn)父類的抽象方法,子類才可以創(chuàng)建對象。
#include<iostream>
#include<string>
using namespace std;
class data
{
public:
string name;
int age;
};
class MM
{
public:
virtual bool empty() = 0;
virtual int size() = 0;
};
class List:public MM
{
public:
bool empty()
{
return 0;
}
int size()
{
return NULL;
}
};
int main()
{
MM* pmm = new List;
pmm->empty();
pmm->size();
}
5.虛析構函數(shù)
virtual修飾的析構函數(shù)就是虛析構函數(shù),當存在子類對象初始化父類指針的時候,父類析構函數(shù)就要是虛析構函數(shù),否則只會釋放父類,存在內(nèi)存泄漏問題
#include<iostream>
using namespace std;
class MM
{
public:
virtual ~MM()
{
cout << "父類" << endl;
}
};
class son:public MM
{
public:
~son()
{
cout << "子類" << endl;
}
};
int main()
{
MM* pmm = new son;
delete pmm;
return 0;
}
6.dynamic_cast類型轉換
- 上行轉換 子類到父類 和
staic_cast差不多 - 下行轉換 父類到子類
dynamic_cast更為安全 - 交叉轉換 多繼承
#include<iostream>
using namespace std;
class MM
{
public:
virtual void print() { cout << "MM" << endl; }
};
class son:public MM
{
public:
void print() { cout << "son" << endl; }
};
class A
{
public:
virtual void print(){}
};
class B
{
public:
virtual void print() {}
};
class C:public A,public B
{
public:
void print()
{
cout << "c" << endl;
}
};
int main()
{
MM* partent = new MM;
son* Son = new son;
//上行轉換----->沒有必要
MM* p = static_cast<MM*>(Son);
MM* pp = dynamic_cast<MM*>(Son);
MM* ppp = Son; //可以
//下行轉換
son* x = dynamic_cast<son*>(partent); //安全,父類沒有virtual會報錯---->多態(tài)
if(!x)
{
printf("error");
} //下行轉換不安全,不會申請成功
A* a = new A;
B* b = dynamic_cast<B*>(a);
b->print();
return 0;
}

7.成員函數(shù)指針
#include<iostream>
#include<functional>
using namespace std;
class MM
{
public:
void print() { cout << "king" << endl; }
static void printData() { cout << "MM" << endl; }
};
int main()
{
void(*p)() = &MM::printData;
p();
//必須通過對象調(diào)用
void(MM::*pp)() = &MM::print;
MM mm;
(mm.*pp)();
//函數(shù)適配器,讓函數(shù)調(diào)用形態(tài)可以適用于別的形態(tài)
auto f = bind(&MM::print, &mm);
f();
return 0;
}
到此這篇關于C++虛函數(shù)和多態(tài)超詳細分析的文章就介紹到這了,更多相關C++虛函數(shù)和多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言之結構體定義 typedef struct 用法詳解和用法小結
這篇文章主要介紹了C語言的結構體定義typedef struct用法詳解和用法小結,typedef是類型定義,typedef struct 是為了使用這個結構體方便,感興趣的同學可以參考閱讀2023-03-03
Cocos2d-x 3.x入門教程(二):Node節(jié)點類
這篇文章主要介紹了Cocos2d-x 3.x入門教程(二):Node節(jié)點類,本文對Node節(jié)點類做了一個簡明講解及Node類提供的函數(shù)做了說明,需要的朋友可以參考下2014-11-11

