日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...

發(fā)布時間:2023/12/3 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天主要講的是虛函數(shù)的override與overload的區(qū)別。首先我們來看一段代碼:

示例代碼

#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");
}

看下輸出結(jié)果吧:

運行結(jié)果

然后我們看一下override、overload與hide從概念上的區(qū)分:

對某函數(shù)func()的overload:指在相同的作用域中定義另一個相同名字的函數(shù),但是這個函數(shù)與func()有這不同的參數(shù)表,或者是參數(shù)類型不完全相同,或者是參數(shù)個數(shù)不同。當程序調(diào)用func()函數(shù)時,系統(tǒng)將根據(jù)實際提供的參數(shù)來選擇最匹配的函數(shù)。

對某函數(shù)func()的override:指在派生類(子類)中定義一個相同名字的函數(shù),并且這個函數(shù)的參數(shù)類型及個數(shù)與func()函數(shù)完全相同。

對外層作用域(基類)中func()函數(shù)的hide:在內(nèi)層作用域(派生類也即子類)中定義一個相同名字的函數(shù),不管參數(shù)類型和個數(shù),這將隱藏在外層作用域中的同名函數(shù)。

好,我們結(jié)合定義來看上面的代碼:

在Father類中void f(int)和void f(double)是就互為重載(overload),因為兩個函數(shù)同名都是f,且在同一個作用域。

Child::f(string i)是對Father::f()進行了隱藏(hide),這意味著:在Child的作用域中Father::f(int)和Father::f(double)是不可見的,且在vs中不會對這種情況進行警告。按理說我們可以直接調(diào)用f(int)f(double),那么我們直接child.f(1),跑出來的結(jié)果是:

Child:f(complex<double>)

這是因為父類的Father::f(int)和Father::f(double)已經(jīng)被hide了,此時在子類中已經(jīng)不能直接調(diào)用父類的方法了。需要通過child.Father::f(1);或者using Father::f(被注釋的哪一行代碼)將父類的f函數(shù)引入才可以。

Child::g(int i)是覆蓋(override)了Father::g(int i)。但是它跟hide的不同是只能通過child.Father::g();的方式調(diào)用父類g函數(shù)。

我們通過虛函數(shù)表來看一下:

虛函數(shù)表查看

chid有自己的虛函數(shù)表,并且其中f(double)和f(int)所指向的函數(shù)與父類虛函數(shù)表中相同,只有g(shù)(int)不同。

還是老規(guī)矩,用圖示來總結(jié):

圖示總結(jié)

最后一行代碼:delete fc是不安全的,因為在本篇以上代碼中父類并不存在虛析構(gòu)函數(shù)。這樣會導致程序內(nèi)存破壞,內(nèi)存中會留下一些部分被銷毀的對象。

從上面代碼的運行結(jié)果可以知道Father *fc = new Child;調(diào)用了Father 和Child兩個類的構(gòu)造函數(shù),但是只調(diào)用了父類Father 的析構(gòu)函數(shù),如果此時Child析構(gòu)函數(shù)內(nèi)有需要釋放內(nèi)存的代碼,那么此時delete fc并不會去調(diào)用Child的析構(gòu)函數(shù),這樣就會造成內(nèi)存泄露,大家一定需要注意。

解決辦法:將Father 的析構(gòu)函數(shù)申明為虛函數(shù)virtual ~Father();這樣,delete fc時Child的析構(gòu)函數(shù)也會被調(diào)用

總結(jié)

以上是生活随笔為你收集整理的vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。