C++ 继承和虚函数
C++ inheritance and virtual funcions
这是我的任务:
设计classes Circle和Square继承自class 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=□
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 的重心(它继承自 class 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=□
cout<<"Area of circle is "<<shape1->area()<<", circumference is "<<shape1->circumference()<<endl;
cout<<"Area of square is "<<shape2->area()<<", circumference is "<<shape2->circumference()<<endl;
}
回答你的问题,不行。您的代码确实显示了一些非常清晰的思路,所以这很好。它只需要完成。所有 classes 的所有数据成员都必须在构造对象时赋值。否则,他们会得到随机值,这绝不是好的做法。所以在 Shape 构造函数中初始化 CG。
此外,如果您想让它们代表 CG,请从圆圈中删除 x 和 y -- 该信息已被继承。
最后,实现一个移动CG的功能,我建议在Shape class中添加一个setter方法,它可以被其他两个继承class es。有了这些,你应该可以开始了。
1.Constructor设计
你将如何设置他们的重心?
Point center_of_grav(a,b);
...
Square square(c); // what's the gravity center ?
您必须设计派生的构造函数,使其具有构造基类所需的所有信息:
Square square(center_of_grav, c);
为此,您必须按以下方式定义它(当然相应地调整 class 定义):
Square::Square(Point p, float a) : Shape(p), lentgh(a) {
// ... reserve this for more complex initisalisations
}
请注意,您的默认构造函数未初始化对象。
2.Design 形状
非常重要: Shape 是具有虚函数的多态class。在这种情况下,您应该养成定义虚拟析构函数的习惯。
小提示:直接创建 Shape 对象是没有意义的。这是一个抽象的概念。没有默认规则来计算可应用于大多数形状的面积或周长。因此,我强烈建议将这两个函数定义为纯虚函数:
class Shape {
...
virtual float circumference(void) =0; // pure virtual
virtual float area(void) = 0;
...
};
优点:一旦你在 class 中有一个纯虚函数,这个 class 就变得抽象了,你将无法实例化那个 [=70= 的对象] 错误。编译器将确保您只实例化抽象概念的具体派生。
3.Make确保您的代码符合要求
好吧,这是一个细节,您当然已经处理好了,但是:
Classes should have specific functions for calculating circumference
and area, as well as for reading data members.
所以我认为您应该预见一些 getter 访问受保护的数据:
示例:
class Shape {
...
Point get_gravity_center();
...
};
Point Shape::get_gravity_center() {
return center_of_gravity;
}
其他的我让你完成。简单地想象一下,您必须在 main()
中打印圆的描述(圆心和半径的坐标),然后您会看到缺少的 getter。
编辑您的问题:
由于我们已经在形状级别为重心定义了 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;
P.S:使用 center_of_gravity 作为形状的成员,您不再需要复制该点的坐标。
这是我的任务:
设计classes Circle和Square继承自class 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=□
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 的重心(它继承自 class 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=□
cout<<"Area of circle is "<<shape1->area()<<", circumference is "<<shape1->circumference()<<endl;
cout<<"Area of square is "<<shape2->area()<<", circumference is "<<shape2->circumference()<<endl;
}
回答你的问题,不行。您的代码确实显示了一些非常清晰的思路,所以这很好。它只需要完成。所有 classes 的所有数据成员都必须在构造对象时赋值。否则,他们会得到随机值,这绝不是好的做法。所以在 Shape 构造函数中初始化 CG。
此外,如果您想让它们代表 CG,请从圆圈中删除 x 和 y -- 该信息已被继承。
最后,实现一个移动CG的功能,我建议在Shape class中添加一个setter方法,它可以被其他两个继承class es。有了这些,你应该可以开始了。
1.Constructor设计
你将如何设置他们的重心?
Point center_of_grav(a,b);
...
Square square(c); // what's the gravity center ?
您必须设计派生的构造函数,使其具有构造基类所需的所有信息:
Square square(center_of_grav, c);
为此,您必须按以下方式定义它(当然相应地调整 class 定义):
Square::Square(Point p, float a) : Shape(p), lentgh(a) {
// ... reserve this for more complex initisalisations
}
请注意,您的默认构造函数未初始化对象。
2.Design 形状
非常重要: Shape 是具有虚函数的多态class。在这种情况下,您应该养成定义虚拟析构函数的习惯。
小提示:直接创建 Shape 对象是没有意义的。这是一个抽象的概念。没有默认规则来计算可应用于大多数形状的面积或周长。因此,我强烈建议将这两个函数定义为纯虚函数:
class Shape {
...
virtual float circumference(void) =0; // pure virtual
virtual float area(void) = 0;
...
};
优点:一旦你在 class 中有一个纯虚函数,这个 class 就变得抽象了,你将无法实例化那个 [=70= 的对象] 错误。编译器将确保您只实例化抽象概念的具体派生。
3.Make确保您的代码符合要求
好吧,这是一个细节,您当然已经处理好了,但是:
Classes should have specific functions for calculating circumference and area, as well as for reading data members.
所以我认为您应该预见一些 getter 访问受保护的数据:
示例:
class Shape {
...
Point get_gravity_center();
...
};
Point Shape::get_gravity_center() {
return center_of_gravity;
}
其他的我让你完成。简单地想象一下,您必须在 main()
中打印圆的描述(圆心和半径的坐标),然后您会看到缺少的 getter。
编辑您的问题:
由于我们已经在形状级别为重心定义了 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;
P.S:使用 center_of_gravity 作为形状的成员,您不再需要复制该点的坐标。