vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...
今天主要講的是虛函數的override與overload的區別。首先我們來看一段代碼:
示例代碼
#include <stdio.h>
#include <string>
#include <iostream>
#include <complex>
using namespace std;
class Father
{
public:
Father();
~Father();
virtual void f(int);
virtual void f(double);
virtual void g(int i = 10);
private:
};
void Father::f(int i)
{
cout<<"Father:f(int)"<<endl;
}
void Father::f(double i)
{
cout<<"Father:f(double)"<<endl;
}
void Father::g(int i)
{
cout<<"Father:g(int):i = "<<i<<endl;
}
Father::Father()
{
cout<<"new father"<<endl;
}
Father::~Father()
{
cout<<"delete father"<<endl;
}
class Child:public Father
{
public:
Child();
~Child();
//using Father::f;
void f(complex<double> i) ;
void g(int i = 20);
private:
};
void Child::f(complex<double> i)
{
cout<<"Child:f(complex<double>)"<<endl;
}
void Child::g(int i)
{
cout<<"Child:g(int):i = "<<i<<endl;
}
Child::Child()
{
cout<<"new Child"<<endl;
}
Child::~Child()
{
cout<<"delete Child"<<endl;
}
void main()
{
Father father;
Child child ;
Father *fc = new Child;
child.f(1);
father.f(1);
child.f(0.1);
father.f(0.1);
child.Father::f(1);
child.Father::f(0.1);
child.g();
child.Father::g();
fc->g();
delete fc;
system("pause");
}
看下輸出結果吧:
運行結果然后我們看一下override、overload與hide從概念上的區分:
對某函數func()的overload:指在相同的作用域中定義另一個相同名字的函數,但是這個函數與func()有這不同的參數表,或者是參數類型不完全相同,或者是參數個數不同。當程序調用func()函數時,系統將根據實際提供的參數來選擇最匹配的函數。
對某函數func()的override:指在派生類(子類)中定義一個相同名字的函數,并且這個函數的參數類型及個數與func()函數完全相同。
對外層作用域(基類)中func()函數的hide:在內層作用域(派生類也即子類)中定義一個相同名字的函數,不管參數類型和個數,這將隱藏在外層作用域中的同名函數。
好,我們結合定義來看上面的代碼:
在Father類中void f(int)和void f(double)是就互為重載(overload),因為兩個函數同名都是f,且在同一個作用域。
Child::f(string i)是對Father::f()進行了隱藏(hide),這意味著:在Child的作用域中Father::f(int)和Father::f(double)是不可見的,且在vs中不會對這種情況進行警告。按理說我們可以直接調用f(int)f(double),那么我們直接child.f(1),跑出來的結果是:
Child:f(complex<double>)
這是因為父類的Father::f(int)和Father::f(double)已經被hide了,此時在子類中已經不能直接調用父類的方法了。需要通過child.Father::f(1);或者using Father::f(被注釋的哪一行代碼)將父類的f函數引入才可以。
Child::g(int i)是覆蓋(override)了Father::g(int i)。但是它跟hide的不同是只能通過child.Father::g();的方式調用父類g函數。
我們通過虛函數表來看一下:
虛函數表查看chid有自己的虛函數表,并且其中f(double)和f(int)所指向的函數與父類虛函數表中相同,只有g(int)不同。
還是老規矩,用圖示來總結:
圖示總結最后一行代碼:delete fc是不安全的,因為在本篇以上代碼中父類并不存在虛析構函數。這樣會導致程序內存破壞,內存中會留下一些部分被銷毀的對象。
從上面代碼的運行結果可以知道Father *fc = new Child;調用了Father 和Child兩個類的構造函數,但是只調用了父類Father 的析構函數,如果此時Child析構函數內有需要釋放內存的代碼,那么此時delete fc并不會去調用Child的析構函數,這樣就會造成內存泄露,大家一定需要注意。
解決辦法:將Father 的析構函數申明為虛函數virtual ~Father();這樣,delete fc時Child的析構函數也會被調用
總結
以上是生活随笔為你收集整理的vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cup过高是什么意思_做青和焙火有什么关
- 下一篇: wps取消分节符(WPS文档中删除分节符