C ++不是我的第一语言选择。而且我不知道我是否认为完全错了。
到目前为止我创造了什么。
我有一个属性的类。指向类Shape的指针。我把类命名为ShapePtr。
ShapePtr.h
class ShapePtr{
public:
ShapePtr():sPtr(0){};
ShapePtr(Shape *s):sPtr(s){};
ShapePtr(const ShapePtr *s){
if( s->sPtr != 0 )
sPtr = s->sPtr->clone();
else
sPtr = 0;
};
friend std::istream& operator>>(std::istream& is, const ShapePt &s);
Shape *sPtr; //Points on Shape or 0
};
ShapePtr.cpp
std::istream& operator>>(std::istream& is, const ShapePtr &s){
std::size_t found;
std::string row, theShape;
while(!is.eof()){
getline(is,row);
found = row.find(":");
theShape= row.substr(0,found);
if(theShape.compare("CIRKEL") == 0)
{
ShapePtr tempSPtr = ShapePtr(new Circle);
/*return*/ ShapePtr test = ShapePtr(tempSPtr.sPtr -> creat(row));
}else if(theShape.compare("POLYGON") == 0){
/*...*/
}else if(theShape.compare("RECTANGLE") == 0){
/*...*/
}else if(theShape.compare("POINT") == 0){
/*...*/
}
/*else if ...*/
};
Class Shape,它是一个带有虚函数creat()的抽象基类。
Shape.h
class Shape{
public:
virtual Shape* creat(std::string row) = 0;
};
Circle是具有不同形状的众多子类之一。
Circle.h
class Circle : public Shape{
public:
Circle();
Circle( double x, double y, double r) : Shape(x, y), radie(r){};
Shape *creat(std::string row);
private:
double radie;
};
Circle.cpp
Circle::Circle()
: Shape(0, 0), radie(0)
{};
Shape * Circle::creat(std::string row){
std::size_t found1, found2;
std::string xstr, ystr, rstr;
double xd, yd, rd;
found1 = row.find("(");
found2 = row.find(",");
//X position
xstr = row.substr(found1 + 1,found2 - found1 -1);
found1 = row.find(",");
found2 = row.find(")");
//Y position
ystr = row.substr(found1 +1,found2 -found1 -1);
found1 = row.find_last_of(":");
//Radie
rstr = row.substr(found1 + 1);
//To double
xd = atof(xstr.c_str());
yd = atof(ystr.c_str());
rd = atof(rstr.c_str());
return new Circle(xd, yd, rd);
};
我的问题是我希望能够使用ShapePtr覆盖运算符>>读取main文件。然后我想重新调整ShapePtr函数中创建的对象。在我上面的代码中,该对象称为test。我在同一行写了一条评论/ return /来澄清。在main中,此对象将添加到列表中。
我无法更改运算符>>返回ShapePtr而不是istream,因为它不再被覆盖。
main应该是这样的
int main(){
ifstream is("fil.dat");
istream_iterator<ShapePtr> shapein(is), endofshapein;
list<ShapePtr> shapelist(shapein, endofshapein );
}
fil.dat的外观如何
POLYGON: { (0,0) (10,0) (5,2) (5,5) }
CIRKEL: (5,5) Radie:4
RECTANGLE: (4,10) Hight:4 Width:2
POINT: (6,7) :1
澄清我的问题。阅读和创建形状不是问题。它们已创建,可以在ShapePtr中打印。问题是如何将它们放到main中的列表中。它可以完成还是我从一开始就创建了很多不好的代码?
我显然没有在论坛上写下我的所有代码,反正我可能写得太多了。但是我写得太多而不是太少。
提前感谢您的回复。
答案 0 :(得分:1)
您并非习惯性地覆盖std::istream& operator>>
,因此std::istream_iterator
将无法做正确的事。
正确的签名是std::istream& operator>>(std::istream& is, ShapePtr &s)
。完成后,您可以分配到s
和return is;
std::istream& operator>>(std::istream& is, ShapePtr &s){
std::string row;
if(getline(is,row)) {
std::size_t found = row.find(":");
std::string theShape = row.substr(0, found);
if(theShape.compare("CIRKEL") == 0){
Circle c;
s = c.create(row);
return is;
} else if(theShape.compare("POLYGON") == 0){
/*...*/
} else if(theShape.compare("RECTANGLE") == 0){
/*...*/
} else if(theShape.compare("POINT") == 0){
/*...*/
} /*else if ...*/
}
return is;
}
但是你的设计存在很多其他问题,比如Circle::create
是一个返回new Circle
而不是构造函数的成员函数,因为你使用原始指针而泄漏Shapes
并且不要注意delete
的事情等。