2014-07-25 129 views
3

在此示例中,我創建基礎對象sphere(2),並將其地址分配給具有類型轉換的派生類指針。然後我可以調用基礎對象sphere(2)中不存在的fun()函數。我認爲這很奇怪,因爲Sphere中根本沒有fun()的定義。但我可以進行類型轉換並調用它。有人可以解釋嗎? 在此先感謝。從基類中不存在的基類中調用派生的方法

PS:輸出是 「哈哈,我半徑2球」

//---------sphere.h-------------- 
#ifndef SPHERE_H 
#define SPHERE_H 

class Sphere{ 
    private: 
     double _radius; 
    public: 
     Sphere(double radius){ 
      _radius = radius; 
     } 
     double getRadius(){ 
      return _radius; 
     } 
}; 

#endif 
//-----------ball.h-------------- 
#ifndef BALL_H 
#define BALL_H 

#include <iostream> 
#include "Sphere.h" 

using namespace std; 

class Ball : public Sphere 
{ 
    private: 
     string _ballName; 
    public: 
     Ball(double radius, string ballName): Sphere(radius){ 
      _ballName = ballName; 
     } 

     string getName(){ 
      return _ballName; 
     } 

     void fun(){ 
      cout << "Haha I am a ball with radius " << getRadius() << endl; 
     } 
     void displayInfo(){ 
      cout << "Name of ball: " << getName() 
         << " radius of ball: " << getRadius() << endl; 
     } 
}; 

#endif 
//-------main.cpp---------------- 
#include "Ball.h" 
#include "Sphere.h" 

int main(){ 
    Ball *ballPtr; 
    Sphere sphere(2); 

    ballPtr = (Ball *)&sphere; 
    ballPtr -> fun(); 

    return 0; 
} 
+2

是不是未定義的行爲很好? – user657267

+0

您可以使用C++ cast而不是c-cast。這裏'dynamic_cast','ballPtr'將是'nullptr'。 – Jarod42

+0

@ Jarod42這裏使用'dynamic_cast'會導致編譯時錯誤,因爲'Sphere'不是多態的。 – user657267

回答

3

那是單純的 「運氣」。您正在調用對象上的某個函數,同時假裝它是另一種類型(BallSphere,但並非全部Sphere都是Balls,而且這肯定不是)。這是未定義的行爲,可以做任何事情,包括敬酒你的貓。小心。

+1

UB的死亡,最糟糕的途徑之一... – SirGuy

1

該函數不是虛擬的,所以它只是被您強制指定的對象指針的類型調用Ball *。 '球'類直接和非虛擬地從'球體'繼承,並且沒有額外的基類,所以 - 幸運的是你! - Sphere::radius成員相對於球的*this的位置在getRadius()中正確,並且您會得到正確的輸出。

相關問題