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 ...*/
};
类Shape是具有虚拟函数creat()的抽象基类。
形状
class Shape{
public:
virtual Shape* creat(std::string row) = 0;
};
圆形,是具有不同形状的许多子类之一。
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重写的运算符>>读取主文件。然后,我想重新调整在ShapePtr函数中创建的对象。在上面的代码中,该对象称为test。我在同一行写了一个注释/ return /来澄清。总的来说,该对象将被添加到列表中。
我无法更改operator >>以返回ShapePtr而不是istream,因为那样便不再覆盖它。
主要应该是这样的
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列表。是可以做到的,还是我从一开始就创建了很多不好的代码?
我显然没有在论坛上写所有代码,反正我可能写太多了。但是我宁愿写太多也不愿写太多。
预先感谢您的答复。
最佳答案
您不是习惯性地覆盖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
,因为您使用的是原始指针并且对的东西等关于c++ - 从重载运算符返回对象>>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47092588/