1. 程式人生 > >C++之建構函式為什麼不能為虛擬函式

C++之建構函式為什麼不能為虛擬函式

針對虛擬函式在說虛擬函式表的時候已經說過了 C++之虛擬函式表,虛擬函式的執行是根據虛擬函式表,而虛擬函式表是在物件生成後,釋放前才存在的,建構函式就是來生成物件的,物件還沒有生成,就把建構函式宣告為了虛擬函式,放到了虛擬函式表中,可是虛擬函式表又不存在,這就矛盾了,故當然不可以把建構函式宣告為虛擬函式,如果這麼做了,編譯器直接報錯。

舉幾個例子實實在在的展示一下虛擬函式表的生命週期:

public:
    Father() {
        this->func();
    }
    ~Father() {}

    virtual void func() {
        cout << "Father::fun()"
<< endl; } }; class Son : public Father { public: Son() { } ~Son() {} virtual void func() { cout << "Son::fun()" << endl; } }; int main() { Son s; system("pause"); return 0; }

輸出結果:

這裡寫圖片描述

這裡Father的建構函式中的this指標是Father類的物件,呼叫func()函式並沒有實現多型,正式因為此時Son類物件還沒有建立,此時的虛擬函式表不存在。

再舉個例子:

#include<iostream>

using namespace std;

class Father {
public:
    Father() {

    }
    ~Father() {
        this->func();
    }

    virtual void func() {
        cout << "Father::fun()" << endl;
    }
};

class Son : public Father {
public:
    Son() {
    }
    ~Son() {}

    virtual
void func() { cout << "Son::fun()" << endl; } }; int main() { Son s; system("pause"); return 0; }

輸出結果:

這裡寫圖片描述

Father的解構函式有個this指標,仍然指向Father的物件,呼叫了func()函式,仍然沒有實現多型,因為Father析構的時候,子類Son已經析構掉了,此時虛擬函式表也已經不存在了,自然也無法實現多型。

再來看一個:

#include<iostream>

using namespace std;

class Father {
public:
    Father() {

    }
    ~Father() {
        this->func();
    }

    virtual void func() {
        cout << "Father::fun()" << endl;
    }

    void foo(){
        this->func();
    }
};

class Son : public Father {
public:
    Son() {
    }
    ~Son() {}

    virtual void func() {
        cout << "Son::fun()" << endl;
    }
};

int main() {
    Son s;
    s.foo();
    system("pause");
    return 0;
}

輸出結果:

這裡寫圖片描述

這個時候就完美的實現了多型,此時Son物件已經生成,也沒有被析構,虛擬函式表是存在的,這就為實現多型奠定了堅實的基礎。

從上面三個例子就能看出虛擬函式表的生命週期是完全依賴於物件的宣告週期的,物件存在虛擬函式表存在,物件不存在虛擬函式表也不存在。

相關推薦

新手學C/C++:解構函式是否必須虛擬函式?什麼情況下才應該定義解構函式虛擬函式

多型是面向物件的一個基本屬性,包括靜態多型(編譯階段)和動態多型(執行階段),靜態多型主要是指函式引數不同產生的多型性,是在編譯階段可以識別的一種多型機制,而執行時多型則主要用於基類指標指向派生類物件時,可以通過基類指標直接呼叫派生類的物件函式,當然這種多型是通過虛擬函式實現的。 虛擬函式的目的

C++中解構函式虛擬函式時呼叫發生了什麼變化

昨天去XX公司面試,面試官問了一個關於C++類解構函式為虛擬函式時,如果是父類的指標用子類來new,如果發生析構時,解構函式是virtual與不是virtual有什麼區別。當時答的不好,回來總結了一下,在機器上實現了一遍,終於搞明白了。記錄下來,以後遇到這種情況自己一定不要

C++建構函式為什麼不能虛擬函式

針對虛擬函式在說虛擬函式表的時候已經說過了 C++之虛擬函式表,虛擬函式的執行是根據虛擬函式表,而虛擬函式表是在物件生成後,釋放前才存在的,建構函式就是來生成物件的,物件還沒有生成,就把建構函式宣告為了虛擬函式,放到了虛擬函式表中,可是虛擬函式表又不存在,這就矛

C++靜態成員函式為什麼不能虛擬函式

應該知道靜態成員函式屬於類,也屬於物件,但終歸屬於類,他在記憶體中只有一份。而虛擬函式必須根據物件型別才能知道呼叫哪一個虛擬函式,故虛擬函式是一定要在物件的基礎上才可以的,兩者一個終歸屬於類,一個必依賴

C++中為什麼建構函式不能定義虛擬函式

關於C++為什麼不支援虛擬建構函式,Bjarne很早以前就在C++Style and Technique FAQ裡面做過回答 Avirtual call is a mechanism to get work done given partialinformation. In particular

C/C++基類的解構函式為什麼必須定義虛擬函式

C/C++基類的解構函式為什麼必須定義為虛擬函式?   為什麼基類的解構函式是虛擬函式? 在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。 (1)第一種情況:沒有多型,建立派生類物件,基類的解構函式不是虛擬函式 #include<

C++函式中那些不可以被宣告虛擬函式函式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C++ 基類的解構函式為什麼需要定義虛擬函式

主要是因為當通過父類的指標或引用指向子類的物件時,刪除子類時父類的解構函式不能被呼叫造成記憶體洩露。 1.當基類的引用指向基類的物件 #include<iostream> #include<cstring> #include<cstdlib> using

C#建構函式

建構函式分為: 1.例項建構函式 2.私有建構函式 3.靜態建構函式 建構函式是一種特殊的方法,主要是為了給初始化物件賦初值。 1.例項建構函式 使用new 表示式建立某個類 的物件時,會使用例項建構函式建立和初始化所有例項成員變數。 public

C++記憶體分佈菱形繼承(無虛擬函式)

       菱形繼承的定義是:兩個子類繼承同一父類,而又有子類同時繼承這兩個子類。例如a,b兩個類同時繼承c,但是又有一個d類同時繼承a,b類。探究的過程還是很有趣的。 菱形繼承的記憶體佈局探究花了我幾天時間,探究起來還是有點難度的。博文中如果有錯誤的地方,歡迎大家指正,

普通函式建構函式、inline函式、友元函式為什麼不能宣告虛擬函式

C++函式中那些不可以被宣告為虛擬函式 常見的不不能宣告為虛擬函式的有:普通函式(非成員函式);靜態成員函式;內聯成員函式;建構函式;友元函式。 1.為什麼C++不支援普通函式為虛擬函式? 普通函式(非成員函式)只能被overload,不能被override,宣告為虛

(四)C#建構函式與解構函式

建構函式與解構函式 建構函式 首先我們看一下例項建構函式的形式 |建構函式修飾符| 識別符號 (|引數列表|) |: base(|引數列表|)| |:this(|引數列表|)| { 建構函式語句塊; } 如果你以前沒學過

為什麼建構函式不能虛擬函式,而解構函式可以虛擬函式

1. 為什麼建構函式不能為虛擬函式?    虛擬函式的呼叫需要虛擬函式表指標,而該指標存放在物件的內容空間中;若建構函式宣告為虛擬函式,那麼由於物件還未建立,還沒有記憶體空間,更沒有虛擬函式表地址用來呼叫虛擬函式——構造函數了。 2. 為什麼解構函式可以為虛擬函式,如果不

c++建構函式和解構函式

1、  建構函式: (1)定義: 1)C++中的類可以定義與類名相同的特殊成員函式,這種與類名相同的成員函式叫做建構函式; 2)建構函式在定義時可以有引數; 3)沒有任何返回型別的宣告。 (2)呼叫: 自動呼叫:一般情況下C++編譯器會自動呼叫建構函式 手動呼叫:在一些情況

C++建構函式、解構函式虛擬函式

建構函式 1.建立物件時會依次呼叫基類和子類的建構函式,各個建構函式負責對自己類中定義的成員的初始化工作。 2.如果使用者不宣告任何建構函式,編譯器將提供一個預設建構函式(default constructor),只要使用者定義了自己的建構函式,不論包不包括預設建構函式,編

(轉載)(C++)淺談多型基類解構函式宣告虛擬函式

主要內容: 1、C++類繼承中的建構函式和解構函式 2、C++多型性中的靜態繫結和動態繫結 3、C++多型性中解構函式宣告為虛擬函式 1、C++類繼承中的建構函式和解構函式 在C++的類繼承中, 建立物件時,首先呼叫基類的建構函式,然後在呼叫下一

C++)淺談多型基類解構函式宣告虛擬函式

主要內容: 1、C++類繼承中的建構函式和解構函式 2、C++多型性中的靜態繫結和動態繫結 3、C++多型性中解構函式宣告為虛擬函式 1、C++類繼承中的建構函式和解構函式 在C++的類繼承中, 建立物件時,首先呼叫基類的建構函式,然後在呼叫下一個派生類的建構函式,依次類推; 析構物件時,其

C++中建構函式、解構函式虛擬函式及普通成員函式的理解

這裡我們主要討論建構函式、解構函式、普通成員函式、虛擬函式,對這幾種函式說說自己的理解。 對建構函式的總結 對建構函式,我們先來看看如下的程式碼 #include <iostream> using namespace std; cla

c++靜態成員函式為什麼不能虛擬函式

其實我覺得這個問題沒有回答的必要,屬於語言概念層面的東西。 class A {  int fun1() { ... } static int func2() { ... } } 首先你要搞清楚什麼是普通成員函式。成員函式是類例項相關的,不同的例項物件呼叫成員函式結果一般都不同。 比如,上面的fun1是成員函式

建構函式和解構函式能否宣告虛擬函式

建構函式不能宣告為虛擬函式,解構函式可以宣告為虛擬函式,而且有時是必須宣告為虛擬函式。 不建議在建構函式和解構函式裡面呼叫虛擬函式。 建構函式不能宣告為虛擬函式的原因是: 解釋一:所謂虛擬函式就是多型情況下只執行一個。而從繼承的概念來講,總是要先構造父類物件,然後才