2017-06-03 100 views
2

嘿這裏的人是我要運行的一些代碼,問題是它不按我打算的方式工作。我無法弄清楚它有什麼問題。我是C++ noob請幫忙。如何在C++中爲孫輩創建超類的虛函數?

#include <iostream> 
#include <cmath> 
#include <stdexcept> 
using namespace std; 

/** 
* Super class 
*/ 
class Shape 
{ 
protected: 
    int _dimensions; 
public: 
    Shape() : _dimensions{0} 
    {}; 
    Shape(int dims) : _dimensions{dims} 
    {}; 

    virtual double getArea() {}; 
    // Because some shapes have no volume. 
    virtual double getVolume() {}; 

    void setDimensions(int dim) 
    { 
     this->_dimensions = dim; 
    }; 
    int getDimensions() 
    { 
     return this->_dimensions; 
    }; 
}; 


/** 
* Extended classes 
*/ 
class TwoDimensionalShape : public Shape 
{ 
public: 
    TwoDimensionalShape() : Shape{2} 
    {}; 
    // This should throw an error 
    double getVolume() { 
     throw logic_error("This shape ain't got area!"); 
    }; 
}; 

class ThreeDimensionalShape : public Shape 
{ 
public: 
    ThreeDimensionalShape() : Shape{3} {}; 
}; 


/** 
* Final Concrete classes extending extended classes 
*/ 
class Circle : public TwoDimensionalShape 
{ 
protected: 
    double _radius; 
public: 
    Circle(double r) : _radius{r} 
    {}; 
    double getArea() 
    { 
     // pi*r^2 
     return M_PI * pow(_radius, 2); 
    } 
}; 

class Square : public TwoDimensionalShape 
{ 
protected: 
    double _side; 
public: 
    Square(double s) : _side{s} 
    {} 
    double getArea() 
    { 
     // s^2 
     return pow(_side, 2); 
    } 
}; 

class Triangle : public TwoDimensionalShape 
{ 
protected: 
    double _base, _height; 
public: 
    Triangle(double b, double h) : _base{b}, _height{h} 
    {}; 
    double getArea() 
    { 
     // b*h/2 
     return _base * _height/2; 
    } 
}; 

class Sphere : public ThreeDimensionalShape 
{ 
protected: 
    double _radius; 
public: 
    Sphere(double r) : _radius{r} 
    {} 
    double getArea() 
    { 
     cout << 4 * M_PI * pow(_radius, 2) << endl; 
     return 4 * M_PI * pow(_radius, 2); 
    } 
    double getVolume() 
    { 
     return (4/3) * M_PI * pow(_radius, 3); 
    } 
}; 

class Cube : public ThreeDimensionalShape 
{ 
protected: 
    double _side; 
public: 
    Cube(double s) : _side{s} 
    {}; 
    double getArea() 
    { 
     // surface area = 6*a^2 
     return 6 * pow(_side, 2); 
    } 
    double getVolume() 
    { 
     // a^3 
     return pow(_side, 3); 
    } 
}; 

class Tetrahedron : public ThreeDimensionalShape 
{ 
protected: 
    double _side; 
public: 
    Tetrahedron(double s) : _side{s} 
    {}; 
    double getArea() 
    { 
     // sqrt(3)*a^2 
     return sqrt(3) * pow(_side, 2); 
    } 
    double getVolume() 
    { 
     // a^3/6sqrt(2) 
     return pow(_side, 3)/(6 * sqrt(2)); 
    } 
}; 

int main() 
{ 
    Shape arr[2]; 
    arr[0] = Circle{10}; 
    arr[1] = Sphere{10}; 

    // This one is accessing the right method. 
    cout << "Area of circle: " << arr[0].getArea() << endl; 
    // This one should access the parent, but accesses the grand parent! 
    // even if it is overridden in parent. 
    cout << "Volume of circle: " << arr[0].getVolume() << endl; 

    // Both of these are accessing methods on grand parent rather than their own!! 
    cout << "Area of sphere: " << arr[1].getArea() << endl; 
    cout << "Volume of sphere: " << arr[1].getVolume() << endl; 

    return 0; 
} 

我不知道爲什麼陣列方法保持在最後三行訪問盛大母公司的功能,但在第一個正確的方法。

+2

遇到*對象切片* – WhiZTiM

+1

https://stackoverflow.com/questions/274626/what-is-object-slicing – juanchopanza

+0

OWH所以,我想在超類對象數組中存儲孫子孫女的問題? – PrimeHero

回答

1

遇到對象切片。下面代碼的部分做的是:以上

Shape arr[2]; 
arr[0] = Circle{10}; 
arr[1] = Sphere{10}; 

每個任務的調用的Shapeslices拷貝賦值操作符關閉子類的對象。您可以通過使用引用或指針實現自己的意圖:

std::unique_ptr<Shape> arr[2]; 
arr[0] = std::make_unique<Circle>(10); 
arr[1] = std::make_unique<Sphere>(10); 
+0

非常感謝這個例子。 – PrimeHero

+0

class std :: unique_ptr '沒有名爲'getArea'的成員 – PrimeHero

+0

@PrimeHero,包裝在'std :: unique_ptr'中,您可以用' - >'not'.'來訪問Shape的成員。示例'arr [0] - > getArea()' – WhiZTiM

0

這是對象切片的情況。你需要把你的對象爲指針,最好爲std::unique_ptr<>到您的陣列 - 或再次最好是std::vector<>

試試這個:

#include <memory> 
#include <vector> 

// ... 

int main() 
{ 
    std::vector<std::unique_ptr<Shape>> vec(2); 
    vec[0] = std::make_unique<Circle>(10); 
    vec[1] = std::make_unique<Sphere>(10); 

    // This one is accessing the right method. 
    cout << "Area of circle: " << vec[0]->getArea() << endl; 
    // This one should access the parent, but accesses the grand parent! 
    // even if it is overridden in parent. 
    cout << "Volume of circle: " << vec[0]->getVolume() << endl; 

    // Both of these are accessing methods on grand parent rather than their own!! 
    cout << "Area of sphere: " << vec[1]->getArea() << endl; 
    cout << "Volume of sphere: " << vec[1]->getVolume() << endl; 

    return 0; 
} 
+0

矢量看起來不錯,我會用矢量去。 – PrimeHero

相關問題