2017-06-03 14 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; 
} 

なぜ、配列メソッドが最後の3行の大親関数にアクセスしているのかわかりませんが、最初の行には正しい方法があります。

+2

あなたは*オブジェクトのスライス* – WhiZTiM

+1

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

+0

OWHを経験しているので、私がしようスーパークラスのオブジェクト配列に孫を格納するのが問題ですか? – PrimeHero

答えて

1

あなたはをスライスオブジェクトを経験している。好ましくはstd::vector<>

はこれを試してみてくださいもう一度か - あなたはあなたの配列にstd::unique_ptr<>として好ましくは、ポインタとしてあなたのオブジェクトを配置する必要があります。

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'でラップされ、' - ''ではなく 'Shape'のメンバーにアクセスします。例 'arr [0] - > getArea()' – WhiZTiM

0

これはオブジェクトのスライシングのケースです。

#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

関連する問題