关于虚函数多态的一个疑惑.请大家指教,高分相赠.该如何解决
关于虚函数多态的一个疑惑.请大家指教,高分相赠.
近日作一道习题:
定义一个具有多态性的基类Shape,继承以下一些类:圆Circle类(坐标点和半径构成),长方形Rectangle类(两个不重合的坐标点构成),三角形Triangle类(三个互不相重合的坐标点构成).定义一些操作,特别是定义求面积操作.
编制应用程序,按文件内容创建各类对象,放在Shape指针向量中.
循环处理向量中的每个元素,求其面积.若为圆,则还要输出其半径(输出半径不是求面积的职能,应另设get成员实现之,它不是虚函数).
shape.txt文件内容如下:
C 123 5 5000
T 1 3 1 50 60 3
C 6 61 30
R 6 8 8 1000
C 2 3 12.3
X
若第一个字符为 'C ',则后面为圆数据:x坐标,y坐标,圆半径三个实数.
若第一个字符为 'R ',则后面为长方形数据:x1,y1,x2,y2坐标.
若第一个字符为 'T ',则后面为三角形数据:x1,y1,x2,y2,x3,y3坐标.
若第一个字符为 'X ',则表示输入结束.
以上便是原题:
本人实现了代码经调试成功输出.但是输出的结果不正确,能够识别子类,但是所得的面积都是一样的,而且3个圆的数据取的半径值也是一样的,我想了一晚上,改了一晚上也想不出问题所在
我的应用程序文件lianxi.cpp如下:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include "Circle.h "
#include "rectangle.h "
#include "triangle.h "
using namespace std;
int main()
{string s1;double a;
vector <double> d;
vector <Shape*> v;
ifstream in( "shape.txt ");
for(string s;getline(in,s);)
{s1= " ";
for(istringstream sin(s);;)
{if(s1== " "){sin> > s1;}
else if(sin> > a) {d.push_back(a);continue;}
else goto ls1;
}
ls1:if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
if(s1== "T "){Triangle b(d[0],d[1],d[2],d[3],d[4],d[5]);v.push_back(&b);}
if(s1== "R "){Rectangle b(d[0],d[1],d[2],d[3]);v.push_back(&b);}
if(s1== "X "){break;}
}cout < <v.size();
for(vector <Shape*> ::iterator it=v.begin();it!=v.end();++it)
{(**it).Area();
(**it).display();
}
}
基类Shape.h的代码为:
#ifndef HEADER_SHAPE
#define HEADER_SHAPE
#include <iostream>
using namespace std;
class Shape
{protected:
double x,y,area;
public:
Shape(double x1,double y1):x(x),y(y){}
virtual void Area(){}
virtual void display(){}
};
#endif
其他的类我就不列出了,主要问题应该就出在这两个文件中,请大家帮我解惑,不胜感激.
------解决方案--------------------
问题在这里:
if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
因为v里面保存的是指针,最终的结果是v里面指向的是同一个元素
(都是最后一个对象)。
这个小程序你参考一下:
int main()
{
vector <int*> v;
for(int i=0; i <4; i++){
int s(i);
v.push_back(&s);
}
for(int i=0; i <4; i++){
cout < <*(v[i]) < <endl;//v里面保存的都是指向最后一个元素3的指针
}
system( "PAUSE ");
return 0;
}
------解决方案--------------------
if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
if(s1== "T "){Triangle b(d[0],d[1],d[2],d[3],d[4],d[5]);v.push_back(&b);}
if(s1== "R "){Rectangle b(d[0],d[1],d[2],d[3]);v.push_back(&b);}
if(s1== "X "){break;}
近日作一道习题:
定义一个具有多态性的基类Shape,继承以下一些类:圆Circle类(坐标点和半径构成),长方形Rectangle类(两个不重合的坐标点构成),三角形Triangle类(三个互不相重合的坐标点构成).定义一些操作,特别是定义求面积操作.
编制应用程序,按文件内容创建各类对象,放在Shape指针向量中.
循环处理向量中的每个元素,求其面积.若为圆,则还要输出其半径(输出半径不是求面积的职能,应另设get成员实现之,它不是虚函数).
shape.txt文件内容如下:
C 123 5 5000
T 1 3 1 50 60 3
C 6 61 30
R 6 8 8 1000
C 2 3 12.3
X
若第一个字符为 'C ',则后面为圆数据:x坐标,y坐标,圆半径三个实数.
若第一个字符为 'R ',则后面为长方形数据:x1,y1,x2,y2坐标.
若第一个字符为 'T ',则后面为三角形数据:x1,y1,x2,y2,x3,y3坐标.
若第一个字符为 'X ',则表示输入结束.
以上便是原题:
本人实现了代码经调试成功输出.但是输出的结果不正确,能够识别子类,但是所得的面积都是一样的,而且3个圆的数据取的半径值也是一样的,我想了一晚上,改了一晚上也想不出问题所在
我的应用程序文件lianxi.cpp如下:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include "Circle.h "
#include "rectangle.h "
#include "triangle.h "
using namespace std;
int main()
{string s1;double a;
vector <double> d;
vector <Shape*> v;
ifstream in( "shape.txt ");
for(string s;getline(in,s);)
{s1= " ";
for(istringstream sin(s);;)
{if(s1== " "){sin> > s1;}
else if(sin> > a) {d.push_back(a);continue;}
else goto ls1;
}
ls1:if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
if(s1== "T "){Triangle b(d[0],d[1],d[2],d[3],d[4],d[5]);v.push_back(&b);}
if(s1== "R "){Rectangle b(d[0],d[1],d[2],d[3]);v.push_back(&b);}
if(s1== "X "){break;}
}cout < <v.size();
for(vector <Shape*> ::iterator it=v.begin();it!=v.end();++it)
{(**it).Area();
(**it).display();
}
}
基类Shape.h的代码为:
#ifndef HEADER_SHAPE
#define HEADER_SHAPE
#include <iostream>
using namespace std;
class Shape
{protected:
double x,y,area;
public:
Shape(double x1,double y1):x(x),y(y){}
virtual void Area(){}
virtual void display(){}
};
#endif
其他的类我就不列出了,主要问题应该就出在这两个文件中,请大家帮我解惑,不胜感激.
------解决方案--------------------
问题在这里:
if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
因为v里面保存的是指针,最终的结果是v里面指向的是同一个元素
(都是最后一个对象)。
这个小程序你参考一下:
int main()
{
vector <int*> v;
for(int i=0; i <4; i++){
int s(i);
v.push_back(&s);
}
for(int i=0; i <4; i++){
cout < <*(v[i]) < <endl;//v里面保存的都是指向最后一个元素3的指针
}
system( "PAUSE ");
return 0;
}
------解决方案--------------------
if(s1== "C "){Circle b(d[0],d[1],d[2]);v.push_back(&b);}
if(s1== "T "){Triangle b(d[0],d[1],d[2],d[3],d[4],d[5]);v.push_back(&b);}
if(s1== "R "){Rectangle b(d[0],d[1],d[2],d[3]);v.push_back(&b);}
if(s1== "X "){break;}