C++ 继承和虚函数

标签 c++ function class inheritance virtual

这是我的任务:

设计继承自Shape类的Circle和Square类(其中包含所有形状的共同特征重心,为特定值移动重心的函数以及虚函数circumference,area和read)。类应具有计算周长和面积以及读取数据成员的特定函数。

这是我所做的:

#include <iostream>

using namespace std;

class Point {
private:
    float x;
    float y;
public:
    Point();
    Point(float,float);
    ~Point();
};

Point::Point() {
}

Point::Point(float a,float b) {
    x=a;
    y=b;
}

Point::~Point() {
}

class Shape {
public:
    Shape(void);
    Shape(Point);
    virtual float circumference(void) {}
    virtual float area(void) {}
protected:
    Point center_of_gravity;
};

Shape::Shape(void) {
}

Shape::Shape(Point a) {
    center_of_gravity=a;
}

//----------------------------------------

class Circle:public Shape {
private:
    float radius;
public:
    float x;
    float y;
    Circle();
    Circle(float);
    virtual float circumference(void);
    virtual float area(void);
};

Circle::Circle(void) {
}

Circle::Circle(float a) {
    radius=a;
}

float Circle::area(void) {
    float area_of_circle;
    const float pi=3.14159;
    area_of_circle=radius*radius*pi;
    return area_of_circle;
}

float Circle::circumference(void) {
    float circumference_of_circle;
    const float pi=3.14159;
    circumference_of_circle=2*radius*pi;
    return circumference_of_circle;
}

//----------------------------------------

class Square:public Shape {
private:
    float length;
public:
    Square();
    Square(float);
    virtual float circumference(void);
    virtual float area(void);
};

Square::Square(void) {
}

Square::Square(float a) {
    length=a;
}

float Square::area(void) {
    float area_of_circle;
    area_of_circle=length*length;
    return area_of_circle;
}

float Square::circumference(void) {
    float circumference_of_square;
    circumference_of_square=4*length;
    return circumference_of_square;
}

int main() {
    float a,b;
    cout<<"Enter coordinates of center of gravity: "<<endl;
    cin>>a>>b;
    Point center_of_grav(a,b);
    cout<<"Enter length of square: "<<endl;
    cin>>a;
    Square square(a);
    cout<<"Enter radius of circle: "<<endl;
    cin>>a;
    Circle circle(a);
    Shape *shape1=&circle;
    Shape *shape2=&square;
    cout<<"Area of circle is "<<shape1->area()<<", circumference is "<<shape1->circumference()<<endl;
    cout<<"Area of square is "<<shape2->area()<<", circumference is "<<shape2->circumference()<<endl;
}

还好吗?如何实现重心移动功能? 如何读取 Circle 和 Square 的重心(它继承自 Shape 类)?当他们说“......以及阅读数据成员”时,他们是认真的(我认为)。

编辑:

在我把所有的建议放在一个地方之后:

    #include <iostream>
    using namespace std;

    class Point{
    private:
    float x;
    float y;
    public:
    Point();
    Point(float,float);
    ~Point();
    friend class Shape;
    };

    Point::Point(){
    }

    Point::Point(float a,float b){
    x=a;
    y=b;
    }

    Point::~Point(){
    }

    //----------------------------------------

    class Shape{
    public:
    Shape(void);
    Shape(Point);
    virtual float area(void)=0;
    virtual float circumference(void)=0;
    protected:
    float x_coordinate;
    float y_coordinate;
    Point center_of_gravity;
    };

    Shape::Shape(void){
    }

    Shape::Shape(Point a){
    center_of_gravity=a;
    x_coordinate=a.x;
    y_coordinate=a.y;
    }

    //----------------------------------------

    class Circle:public Shape{
    private:
    float radius;
    public:
    Circle();
    Circle(Point,float);
    virtual float area(void);
    virtual float circumference(void);
    };

    Circle::Circle(void){
    radius=0;
    }

    Circle::Circle(Point p,float a) : Shape(p), radius(a){
    }

    float Circle::area(void){
    float area_of_circle;
    const float pi=3.14159;
    area_of_circle=radius*radius*pi;
    return area_of_circle;
    }

    float Circle::circumference(void){
    float circumference_of_circle;
    const float pi=3.14159;
    circumference_of_circle=2*radius*pi;
    return circumference_of_circle;
    }

    //----------------------------------------

    class Square:public Shape{
    private:
    float length;
    public:
    Square();
    Square(Point,float);
    virtual float area(void);
    virtual float circumference(void);
    };

    Square::Square(void){
    length=0;
    }

    Square::Square(Point p,float a) : Shape(p), length(a){
    }


    float Square::area(void){
    float area_of_circle;
    area_of_circle=length*length;
    return area_of_circle;
    }

    float Square::circumference(void){
    float circumference_of_square;
    circumference_of_square=4*length;
    return circumference_of_square;
    }

    //----------------------------------------

    int main(){
    float a,b;
    cout<<"Enter coordinates of center of gravity: "<<endl;
    cin>>a>>b;
    Point center_of_grav(a,b);
    cout<<"Enter length of square: "<<endl;
    cin>>a;
    Square square(center_of_grav,a);
    cout<<"Enter radius of circle: "<<endl;
    cin>>a;
    Circle circle(center_of_grav,a);
    Shape *shape1=&circle;
    Shape *shape2=&square;
    cout<<"Area of circle is "<<shape1->area()<<", circumference is "<<shape1->circumference()<<endl;
    cout<<"Area of square is "<<shape2->area()<<", circumference is "<<shape2->circumference()<<endl;
    }

最佳答案

1.构造函数设计

您将如何设置他们的重心?

Point center_of_grav(a,b);
...
Square square(c);   // what's the gravity center ?  

您必须设计派生的构造函数,使其具有构造基类所需的所有信息:

Square square(center_of_grav, c); 

为此,您必须按以下方式定义它(当然相应地调整类定义):

Square::Square(Point p, float a) : Shape(p), lentgh(a) {
    // ... reserve this for more complex initisalisations
}

请注意,您的默认构造函数未初始化对象。

2.造型设计

非常重要:Shape 是一个带有虚函数的多态类。在这种情况下,您应该养成定义虚拟析构函数的习惯。

小注:直接创建一个 Shape 对象是没有意义的。这是一个抽象的概念。没有默认规则来计算可应用于大多数形状的面积或周长。因此,我强烈建议将这两个函数定义为纯虚函数:

class Shape {
    ...
    virtual float circumference(void) =0;  // pure virtual
    virtual float area(void) = 0; 
    ...
};

优点:一旦你在一个类中有了纯虚函数,这个类就变成了抽象的,你将无法错误地实例化那个类的对象。编译器将确保您只实例化抽象概念的具体派生。

3.确保您的代码符合要求

嗯,这是一个细节,您当然已经处理好了,但是:

Classes should have specific functions for calculating circumference and area, as well as for reading data members.

所以我认为你应该预见到一些 getters 来访问 protected 数据:

示例:

class Shape {
    ...
    Point get_gravity_center();  
    ...
};

Point Shape::get_gravity_center() {
    return center_of_gravity;
}

我让你完成其他的。简单地想象一下,您必须在 main() 中打印圆的描述(圆心和半径的坐标),您会看到缺少的 getter。

编辑您的问题:

因为我们已经在形状级别定义了重心的 setter/getter ,所以您不需要在派生类中再次定义它。然后您可以简单地在 main() 中调用它。问题是您还需要访问该点的坐标。所以:

class Point {
    ... 
    float get_x() { return x; }
    float get_y() { return y; }
    ...
};

有了这个你可以在main()中写:

cout << "Circle of center ("<<circle.get_gravity_center().get_x()<<","
                            << circle.get_gravity_center().get_y()<<")"<<endl;

附言:有了 center_of_gravity 作为形状的成员,您不再需要复制该点的坐标。

关于C++ 继承和虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30715219/

相关文章:

java - Ant编译创建不需要的java类文件

c++ - 如何将 BUCK 构建与具有多个同名文件的 pod 一起使用?

c++ - 如何移动多个矩形作为碰撞响应?

java - 如何从字符串中获取类型?

r - 如何引用函数中的列

c - 为什么在一个函数中声明的 union 类型在另一个函数中使用是无效的?

java - 尝试从类变量中提取包名称时出错

c++ - 具有不变返回类型的模板类中的交换运算符

c++ - 按位移位将 unsigned char 提升为 int

python - 使用当前类实例的属性作为方法参数的默认值