C ++继承和虚函数

时间:2015-06-08 17:11:45

标签: c++ function class inheritance virtual

这是我的任务:

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

这就是我所做的:

#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类)?当他们说&#34; ...以及阅读数据成员时,他们的意思是(我认为)。&#34;

编辑:

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

    #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;
    }

2 个答案:

答案 0 :(得分:1)

要回答你的问题,不行。你的代码确实显示了一些非常清晰的想法,所以这很好。它只需要完成。构造对象时,必须为所有类的所有数据成员指定值。否则,它们会得到随机值,这绝不是好习惯。所以在Shape构造函数中初始化CG。

另外,从圆圈中删除x和y,如果你的意思是代表CG - 那些信息已经被继承。

最后,为了实现移动CG的功能,我建议在Shape类中添加一个setter方法,它可以被其他两个类继承。有了它,你应该好好去。

答案 1 :(得分:1)

1.Constructor design

你将如何设置他们的重力中心?

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.确保您的代码符合要求

嗯,这是一个细节,你当然已经照顾它了,但是:

  

类应具有计算周长的特定函数   和区域,以及阅读数据成员

所以我认为你应该预见一些获取者可以访问受保护的数据:

示例:

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

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

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

编辑以下问题:

当我们在形状级别定义重心的吸气剂时,您不需要在导数中再次定义它。然后你可以简单地在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;

P.S:将center_of_gravity作为形状的成员,您不再需要复制该点的坐标。