12.2、声明一个基类OBJ,该基类保护成员m_Name,由此派生出立方体和球体的派生类分别为CUBE和SPHERE,立方体的成员为边长m_R,球体的成员为半径m_Radial,在程序中初始化一个立方体和球体的对象,并将立方体边长设置为3.2,球体半径设置为3.5,并使用基类的指针,通过动态绑定到之前的立方体和球体的对象,使用该基类指针访问并输出立方体和球体的体积。
#include <iostream>
#include <cmath>
#include <stdexcept>
#include <memory>
class OBJ
{
public:
OBJ(const std::string &name) : m_Name(name) {}
virtual ~OBJ() = default;
virtual float volume() const = 0;
const std::string getName() const { return m_Name; }
void setName(const std::string &name) { m_Name = name; }
protected:
std::string m_Name;
};
class CUBE : public OBJ
{
public:
CUBE(const std::string &name, float r) : OBJ(name), m_R(r)
{
if (r <= 0.0f)
throw std::invalid_argument("invalid cube");
}
float getR() const { return m_R; }
void setR(float r) { m_R = r; }
virtual float volume() const { return std::pow(m_R, 3); }
private:
float m_R;
};
class SPHERE : public OBJ
{
public:
SPHERE(const std::string &name, float r) : OBJ(name), m_Radial(r)
{
if (r <= 0.0f)
throw std::invalid_argument("invalid sphere");
}
float getRadial() const { return m_Radial; }
void setRadial(float r) { m_Radial = r; }
virtual float volume() const { return static_cast<float>(std::pow(m_Radial, 3) * M_PI * 4.0 / 3.0); }
private:
float m_Radial;
};
int main()
{
OBJ *p1 = new CUBE("cube1", 3.2f);
OBJ *p2 = new SPHERE("sphere1", 3.5f);
std::cout << p1->getName() << "'s volume is " << p1->volume() << '\n';
std::cout << p2->getName() << "'s volume is " << p2->volume() << '\n';
delete p1;
delete p2;
return 0;
}