2015-11-19 67 views
1

這裏是我的代碼:當執行objPtr->displayModel()基類指針只獲取派生類變量值而不是基類變量值爲什麼?

#include<iostream> 
using namespace std; 

class Shape 
{ 
    char obj; 

public: 
    int j; 
    Shape(); 
    void displayModel(); 
}; 

class Line : public Shape 
{ 
    char obj; 

public: 
    Line(); 
    void displayModel(); 
}; 

Shape::Shape() 
{ 
    obj = 'S'; 
    j = 1; 
} 

void ::Shape::displayModel() 
{ 
    cout << obj; 
    cout << " Shape j:" << j << endl; 
} 

Line::Line() 
{ 
    obj = 'L'; 
    j = 5; 
} 

void Line::displayModel() 
{ 
    cout << obj; 
    cout << " Line j:" << j << endl; 
} 

int main() 
{ 
    Shape *objPtr = NULL, s; 
    Line l; 
    objPtr = &l; 

    s.displayModel(); 
    l.displayModel(); 
    objPtr->displayModel(); 

    return 0; 
} 

我的疑問是爲什麼j=5而不是j=1?我知道objPtr被分配到對象l的地址。但是我還沒有在Shape::displayModel()中聲明virtual關鍵字,所以這並不意味着編譯器應該檢查對象的type而不是它指向的內容?或者是否僅在函數調用時發生virtual關鍵字聲明且不包含變量?

所以基本上我的疑問是爲什麼objPtr->displayModel()打印j=5而不是j=1

+0

您的基類不是虛擬的。 'objPtr-> displayModel()'調用'Shape :: displayModel()'打印'Shape :: j'。 –

+0

@Jonathan Potter但是接下來不是Shape :: j的值初始化爲1.那麼爲什麼j = 5呢? – Mutex202

回答

2

爲什麼要j有所不同?只有一個j,在Shape中聲明。當你從Shape派生出來的時候,你並沒有增加更多的j,那麼在Line中也需要一些j。在另一方面,你有單獨objShapeLine,所以這就是爲什麼你的程序打印

S Shape j:1 
L Line j:5 
S Shape j:5 

注:如果您void Shape::displayModel()virtual,呼叫objPtr->displayModel();將傳播到void Line::displayModel()相反,你會得到2個L S:

S Shape j:1 
L Line j:5 
L Line j:5 
+0

那麼這是否意味着objPtr-> j取對象l的值l.j?那麼,基本上objPtr會指向什麼對象會得到對象j的值是對的? – Mutex202

+0

是的,但請記住,它實際上是'l'形狀的'j'。 – LogicStuff

+0

是的,我知道。我之前對objPtr-> j會得到什麼值,Shape的對象的s.j值或Line對象的l.j值有疑問。現在很清楚,非常感謝。 – Mutex202

0

LogicStuff是正確的。

添加標記,就像cout << 'In Shape::displayModel() function'cout << 'In Line::displayModel() function'

應該幫助您瞭解追加。

0

我沒有嘗試過的代碼,但乍一看我可以告訴你兩兩件事:

首先是要在C++的多態性,你需要使用「虛擬」的關鍵字。具有虛擬功能或虛擬方法的類被稱爲多態。

class Shape{ 
private: 
    char obj; 
public: 
    int j; 
    Shape(); 
    virtual void displayModel(); 
}; 

其次是你應該用基本靜態類型聲明你的對象,然後使用派生的動態類型來實例化它。

Shape *objPtr = new Line(); 

通過使用虛擬功能的程序「記住」的動態型,因此可以調用即使在對象被upcasted到更一般的類型特定的方法。

請記住,編譯器執行此操作的方式是爲具有虛擬函數的類提供虛擬表,從而消耗更多內存。

希望這會有幫助

相關問題