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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?

發布時間:2025/4/16 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如題,當一個類為基類的時候,通常其析構函數被聲明為虛函數,這是為啥?

class BaseCls
{
public:
BaseCls() { printf("BaseCls()n"); }
~BaseCls() { printf("~BaseCls()n"); }
void test_func() { printf("Base::test_func()n"); }
};
class SubCls : public BaseCls
{
public:
SubCls() { printf("SubCls()n"); }
~SubCls() { printf("~SubCls()n"); }
void test_func() { printf("SubCls::test_func()n");
};
int main(void)
{
BaseCls *base = new SubCls;
base->test_func();
delete base;
return 0;
}

編譯運行:

在main()函數中,定義了BaseCls類型指針,根據賦值兼容性原則,該指針可以指向動態生成子類SubCls對象的地址,此時動態生成的SubCls對象已經被充當基類使用,因為BaseCls中的test_func()函數是普通函數(并非虛函數)不能發生多態,所以打印的是基類的”Base::test_func()n”。

代碼”delete base;”我們希望用來釋放SubCls的空間,即調用SubCls的析構函數,釋放完畢后BaseCls的析構函數。然而編譯器只是根據指針類型是BaseCls而只是調用BaseCls的析構函數,SubCls的析構函數得不到調用,若在SubCls構造函數中動態分配的空間,在析構函數釋放空間,那么這樣就造成內存泄漏了。

如何改進?讓基類BaseCls的析構函數聲明為虛函數,使其在delete base時發生多態即可:

class BaseCls
{
public:
//...
virtual ~BaseCls()
{
printf("~BaseCls()n");
}
//...
};

編譯運行:

將構造函數中聲明為virtual后,編譯器就不會簡單的只根據base指針的類型而決定調用對象的構造函數,而是依據指針base所指向的實際對象而調用其構造函數,這不就是多態嗎?

最后,再補充兩個問題?
(1) 析構函數可以被聲明為虛函數,那構造函數可以聲明為虛函數嗎?
- 答案是不可以。因為虛函數的調用依靠于虛函數表。然而在構造函數執行完畢后,虛函數表指針才被正確初始化。


(2) 構造函數不可以被聲明為虛函數,那么構造函數的實現體中,可以實現多態嗎?
- 答案還是不可以。因為析構函數一旦被調用,虛函數表指針就會銷毀了。那么同理,在構造函數中實現體中也不可能發生多態行為,因為在構造函數執行時,虛函數表指針還沒被正確初始化。

總結

以上是生活随笔為你收集整理的基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。