2016-04-07 180 views
0

我正在練習繼承,我有一個叫做Person的基類。 Person有一個名爲age的變量,並且在Person類的構造函數中,我設置了age5並將年齡打印到屏幕上。我有另一個類叫ballPerson,從Person繼承age和設置age等於6。當我爲我的Person課程和我的ballPerson課程創建對象時,值5Person課程中的age的值)會打印兩次。爲什麼?爲什麼繼承值打印兩次?

person.h

class Person 
{ 
public: 
    Person(); 
    int age; 
    ~Person(); 
}; 

Person.cpp

Person::Person() : age(5) 
{ 
    std::cout << age; 
} 

ballPerson.h

class ballPerson : public Person 
{ 
public: 
    ballPerson(); 
    ~ballPerson(); 
}; 

ballPerson.cpp

ballPerson::ballPerson() 
{ 
    age = 6; 
    std::cout << age; 
} 

main.cpp中

int main() 
{ 
    Person p; 
    ballPerson bp; 


    system("pause"); 
    return 0; 
} 

回答

2

這將打印5

Person p; 

而這種打印56

ballPerson bp; 

由於Person(基類)的構造是從ballPerson構造調用。

+0

我從來沒有在我的球人類創建人的實例,以便它爲什麼叫這個人的構造? – RoundSquare

+1

@RoundSquare因爲它是基類,所以必須先初始化 –

+0

謝謝。我想我現在明白了 – RoundSquare

0

正如Anton所說,當您實例化對象時,子類會調用其父類的構造函數。但是,爲什麼呢?

那麼,它是按照定義(http://en.cppreference.com/w/cpp/language/derived_class)完成的,如果我們看一下內存,我們可以自己看。上述

ballPerson::ballPerson (this=0x7fffffffe400) 
(gdb) p this 
$14 = (ballPerson * const) 0x7fffffffe400 
(gdb) p *this 
$15 = {<Person> = {age = 4197216}, <No data fields>} 

看,我們是ballPerson構造函數中,this0x7fffffffe400。諮詢this,我們看到它'有'Person對象的字段age(迄今未初始化)。

ballPerson構造函數被初始化後,剛準備好執行,編譯器調用Person構造函數。

0x400af0 <ballPerson::ballPerson()+24> callq 0x400a96 <Person::Person()> 

,我們可以看到:

Person::Person (this=0x7fffffffe400) 
(gdb) p this 
$6 = (Person * const) 0x7fffffffe400 
(gdb) p *this 
$7 = {age = 4197216} 

它的Person構造和它的使用相同的this指針,指向同一個0x7fffffffe400。之後,運行ballPerson構造函數中的代碼。

換句話說,想象它的C和C++之間的混合,代碼爲:

ballPerson::ballPerson(ballPerson *this) 
{ 
    Person(this); 
    this->age = 6; 
    std::cout << this->age; 
}