爲什麼會發生這種情況?有趣的C++抽象函數
當U創建在C + +實施例的抽象類:即B類後A類(其具有純虛函數) 從類繼承的
如果類A具有構造函數名爲A() 假設我創建了對象的B類然後編譯器初始化基類,即class A然後初始化class B然後.......?
首先,我們不能訪問沒有Object的任何類的構造函數,那麼如果我們不能創建抽象類的對象,它如何初始化抽象類的構造函數。
爲什麼會發生這種情況?有趣的C++抽象函數
當U創建在C + +實施例的抽象類:即B類後A類(其具有純虛函數) 從類繼承的
如果類A具有構造函數名爲A() 假設我創建了對象的B類然後編譯器初始化基類,即class A然後初始化class B然後.......?
首先,我們不能訪問沒有Object的任何類的構造函數,那麼如果我們不能創建抽象類的對象,它如何初始化抽象類的構造函數。
快速回答:構造函數是特殊的。
當A的構造函數仍在運行時,正在構造的對象還不是真正的A類型,它仍在構造中。當構造函數完成時,它現在是A.對於派生的B,它是相同的.A的構造函數首先運行。現在它是A.然後B的構造函數開始運行。在這期間,對象仍然是一個答案。只有當B的構造函數完成後,它纔會變爲B.
您可以通過嘗試從構造函數調用純虛函數來驗證這一點。如果函數在A中定義,並且B的構造函數調用它,則會出現運行時錯誤,而不是運行B的覆蓋,因爲對象不是B類型。
由於純虛擬函數,編譯器不允許生成構造A的代碼。但是它會生成代碼來構建一個A,作爲構建B的過程的一部分。這裏沒有涉及的魔術。你不能構造A的規則是由語言規則強加的,而不是物理的。語言升降機下B.
class A
是抽象的,但是class B
不是。爲了構建class B
,它必須實現class A
的所有純虛擬成員函數。
class A
{
public:
A() {}
virtual ~A() {}
virtual void foo() = 0; // pure virtual
int i;
};
class B : public A
{
public:
B() {}
virtual ~B() {}
virtual void foo() {}
int j;
};
A類佈局可能是這樣的:
+---------+ +---------+ | vftable | --> | ~A() | --> address of A::~A() +---------+ +---------+ | i | | foo() | --> NULL, pure virtual +---------+ +---------+
的B級佈局可能是這樣的:
+---------+ +---------+ | vftable | --> | ~B() | --> address of B::~B() +---------+ +---------+ | i | | foo() | --> address of B::foo() +---------+ +---------+ | j | +---------+
struct A {
A(int x) {..}
virtual void do() = 0;
};
struct B : public A {
B() : A(13) {} // <--- there you see how we give params to A c'tor
virtual void do() {..}
};
And if class A has constructor called A() suppose i created an
Object of class B then the compiler initializes the base class
first i.e.class A and then initialize the class B
Then.......?
事實上的構造對象的特殊情況這條規則,你有它周圍的錯誤的方式:
當你創建類B的對象B的構造函數叫做。
如果不指定B構造函數是如何調用構造函數,則編譯器會自動插入在初始化列表中的第一個動作A.
的默認構造函數的調用如果你不想使用默認構造函數,您必須明確地將調用放到適當的A構造函數中作爲初始化程序列表中的第一個元素。
當A的建設完成後,B的建設將繼續進行。
First thing is we can not access a constructor of any class without an Object
then how it is initialize the constructor of abstract class if we can not create
an object of abstract class .
你把上面的話說得像是考慮A和B不同的事情。 B類的一個對象也是A類的一個對象。它是整個對象是有效的。整個對象是B類,但它包含(作爲同一對象的一部分)來自A類的所有信息。
僅僅因爲您不能直接實例化類A
並不意味着不可能實例化類A
。你不允許實例化A
,因爲編譯器知道A
是抽象的,並且拒絕你編寫的任何代碼,試圖直接實例化A
。它禁止這樣的代碼:
A a;
new A();
什麼使一個類的抽象是它有純虛擬方法。不過,沒有什麼內在地阻止這樣的類被實例化。 C++標準只是說它不被允許。編譯器完全能夠生成指令來實例化抽象類。它所要做的就是保留適量的內存,然後調用構造函數,就像它爲非抽象類一樣。
當您實例化B
時,該類的所有內存都被一次性分配。由於所有字節都存在,因此基本上有一個A
實例,可以由構造函數初始化。 (但請注意,內存沒有正式考慮A
類型的對象,直到後A
構造已經完成運行。)的A
構造函數運行,然後B
構造運行。
感謝您的答案,但我想知道它是如何創建抽象類的內部對象?????? – 2008-12-13 09:59:57
對一個簡單問題的精心解答可笑。 – 2008-12-13 17:11:35