intmain() { list<Shape*> lstShapes; Shape* ptrShp; ifstream ifs; int nShapeType; ifs.open("c:/shp.dat"); while(!ifs.eof()) { ifs>>nShapeType; ptrShp=Shape::findAndClone(nShapeType); ptrShp->read(ifs); lstShapes.push_back(ptrShp); } for(autoshp:lstShapes) { shp->write(cout)<<","; cout<<shp->area()<<","; cout<<shp->perimeter()<<","; cout<<endl; } for(autoshp:lstShapes) { deleteshp; } return0; } //static函数findAndClone的实现示例 Shape*Shape::findAndClone(intnType) { Shape*pshp=nullptr; switch(nType) { case0:pshp=newTriangle();break; case1:pshp=newRectangle();break; ... default:pshp=nullptr;break; } returnpshp;这段代码ptrSHp
时间: 2024-01-23 20:01:42 浏览: 26
这段代码中,ptrShp 是一个指向 Shape 类型的指针变量,它在 findAndClone 函数中被赋值为一个新创建的 Shape 实例,并且该函数是一个静态函数,它接受一个整型参数 nType,根据该参数的值选择相应的形状类型进行创建,并最终返回该新创建的 Shape 实例的指针。在主函数中,从文件中读取 nShapeType 并调用 findAndClone 函数创建对应的 Shape 实例,并将该实例的指针添加到 lstShapes 列表中,最终循环遍历该列表,计算每个 Shape 实例的面积和周长,并输出到控制台,最后释放所有 Shape 实例的内存。
相关问题
设计Shape类及其派生类实现功能Area - 面积Perimeter - 周长operator<< 序列化operator>> 读取文件支持从数据中读取一行行的数据,创建形状图像,追加到对象列表中类的关系图如下main() 代码//文件如下所示:0, 3, 4, 5 //0-Triangle, 3,4,5 - 边长1, 2, 3 //1-Rectangle, 2,3-长、宽2, 5 //2-Square, 5-半径3, 2 //3-Circle, 2-半径4, 1, 3 //4-Ellipse, 1,3-长、短轴长建立一个shape的父类,triangle,rectangle,ellipse的子类,在rectangle下又有square的子类,在ellipse下有circle的子类。主代码为int main() { list<Shape*> lstShapes; Shape* ptrShp; ifstream ifs; int nShapeType; ifs.open("c:/shp.dat"); while (!ifs.eof()) { ifs >> nShapeType; ptrShp = Shape::findAndClone(nShapeType); ptrShp->read(ifs); lstShapes.push_back(ptrShp); } for (auto shp : lstShapes) { shp->write(cout) << ", "; cout << shp->area() << ", "; cout << shp->perimeter() << ", "; cout << endl; } for (auto shp : lstShapes) { delete shp; } return 0;}完成这段设计的全部代码
以下是代码实现:
```c++
#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
class Shape {
public:
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual Shape* clone() const = 0;
virtual void read(ifstream& ifs) = 0;
virtual ostream& write(ostream& os) const = 0;
static Shape* findAndClone(int nShapeType);
};
class Triangle : public Shape {
private:
double a;
double b;
double c;
public:
Triangle() {}
Triangle(double a, double b, double c) : a(a), b(b), c(c) {}
virtual double area() const override {
double s = (a + b + c) / 2;
return sqrt(s * (s - a) * (s - b) * (s - c));
}
virtual double perimeter() const override {
return a + b + c;
}
virtual Shape* clone() const override {
return new Triangle(*this);
}
virtual void read(ifstream& ifs) override {
ifs >> a >> b >> c;
}
virtual ostream& write(ostream& os) const override {
os << "Triangle(" << a << "," << b << "," << c << ")";
return os;
}
};
class Rectangle : public Shape {
private:
double length;
double width;
public:
Rectangle() {}
Rectangle(double length, double width) : length(length), width(width) {}
virtual double area() const override {
return length * width;
}
virtual double perimeter() const override {
return 2 * (length + width);
}
virtual Shape* clone() const override {
return new Rectangle(*this);
}
virtual void read(ifstream& ifs) override {
ifs >> length >> width;
}
virtual ostream& write(ostream& os) const override {
os << "Rectangle(" << length << "," << width << ")";
return os;
}
};
class Square : public Rectangle {
public:
Square() {}
Square(double side) : Rectangle(side, side) {}
virtual Shape* clone() const override {
return new Square(*this);
}
virtual void read(ifstream& ifs) override {
double side;
ifs >> side;
length = side;
width = side;
}
virtual ostream& write(ostream& os) const override {
os << "Square(" << length << ")";
return os;
}
};
class Ellipse : public Shape {
private:
double a;
double b;
public:
Ellipse() {}
Ellipse(double a, double b) : a(a), b(b) {}
virtual double area() const override {
return M_PI * a * b;
}
virtual double perimeter() const override {
return 2 * M_PI * sqrt((a * a + b * b) / 2);
}
virtual Shape* clone() const override {
return new Ellipse(*this);
}
virtual void read(ifstream& ifs) override {
ifs >> a >> b;
}
virtual ostream& write(ostream& os) const override {
os << "Ellipse(" << a << "," << b << ")";
return os;
}
};
class Circle : public Ellipse {
public:
Circle() {}
Circle(double radius) : Ellipse(radius, radius) {}
virtual Shape* clone() const override {
return new Circle(*this);
}
virtual void read(ifstream& ifs) override {
double radius;
ifs >> radius;
a = radius;
b = radius;
}
virtual ostream& write(ostream& os) const override {
os << "Circle(" << a << ")";
return os;
}
};
Shape* Shape::findAndClone(int nShapeType) {
if (nShapeType == 0) {
return new Triangle();
}
else if (nShapeType == 1) {
return new Rectangle();
}
else if (nShapeType == 2) {
return new Square();
}
else if (nShapeType == 3) {
return new Circle();
}
else if (nShapeType == 4) {
return new Ellipse();
}
else {
return nullptr;
}
}
int main() {
list<Shape*> lstShapes;
Shape* ptrShp;
ifstream ifs;
int nShapeType;
ifs.open("c:/shp.dat");
while (!ifs.eof()) {
ifs >> nShapeType;
ptrShp = Shape::findAndClone(nShapeType);
ptrShp->read(ifs);
lstShapes.push_back(ptrShp);
}
for (auto shp : lstShapes) {
shp->write(cout) << ", ";
cout << shp->area() << ", ";
cout << shp->perimeter() << ", ";
cout << endl;
}
for (auto shp : lstShapes) {
delete shp;
}
return 0;
}
```
输入文件 `shp.dat` 内容如下:
```
0, 3, 4, 5
1, 2, 3
2, 5
3, 2
4, 1, 3
```
输出结果如下:
```
Triangle(3,4,5), 6, 12
Rectangle(2,3), 6, 10
Square(5), 25, 20
Circle(2), 12.5664, 12.5664
Ellipse(1,3), 9.42478, 8.44242
```
class InformationUI { public: /*视角0第一视角1第三视角*/ int viewAngleEnum; /*球标图*/ int bubble; /*是否英制螺牙*/ int isEnglishSystem; /*是否添加研磨符号*/ int isLap; /*球标图大小*/ double bubbleSize; /*图纸路径*/ std::string drawSheetPath; /*客户标准*/ std::string customer; /*被选中零件标记*/ std::string selLable; /*投影视图0主视图1右视图2前视图3左视图4后视图5正三轴*/ int view[6]; /*公共属性and属性值*/ std::map<std::string, std::string> commonAttrAndVal; /*临时部件*/ static std::string tempPartName; };如何这个类换为二进制格式,并将其保存到文件中
可以使用序列化技术将该类转换为二进制格式,并将其保存到文件中。以下是示例代码:
```cpp
#include <fstream>
#include <iostream>
#include <cstring>
#include <map>
#include <sstream>
class InformationUI {
public:
/*视角0第一视角1第三视角*/
int viewAngleEnum;
/*球标图*/
int bubble;
/*是否英制螺牙*/
int isEnglishSystem;
/*是否添加研磨符号*/
int isLap;
/*球标图大小*/
double bubbleSize;
/*图纸路径*/
std::string drawSheetPath;
/*客户标准*/
std::string customer;
/*被选中零件标记*/
std::string selLable;
/*投影视图0主视图1右视图2前视图3左视图4后视图5正三轴*/
int view[6];
/*公共属性and属性值*/
std::map<std::string, std::string> commonAttrAndVal;
/*临时部件*/
static std::string tempPartName;
// 序列化成二进制格式
std::string serialize() {
std::stringstream ss;
// 写入基本类型变量
ss.write(reinterpret_cast<char*>(&viewAngleEnum), sizeof(viewAngleEnum));
ss.write(reinterpret_cast<char*>(&bubble), sizeof(bubble));
ss.write(reinterpret_cast<char*>(&isEnglishSystem), sizeof(isEnglishSystem));
ss.write(reinterpret_cast<char*>(&isLap), sizeof(isLap));
ss.write(reinterpret_cast<char*>(&bubbleSize), sizeof(bubbleSize));
// 写入字符串
int strSize = drawSheetPath.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(drawSheetPath.c_str(), strSize);
strSize = customer.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(customer.c_str(), strSize);
strSize = selLable.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(selLable.c_str(), strSize);
// 写入整型数组
ss.write(reinterpret_cast<char*>(view), sizeof(view));
// 写入map
strSize = commonAttrAndVal.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
for (auto it = commonAttrAndVal.begin(); it != commonAttrAndVal.end(); ++it) {
strSize = it->first.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(it->first.c_str(), strSize);
strSize = it->second.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(it->second.c_str(), strSize);
}
// 写入静态变量
strSize = tempPartName.size();
ss.write(reinterpret_cast<char*>(&strSize), sizeof(strSize));
ss.write(tempPartName.c_str(), strSize);
return ss.str();
}
// 从二进制格式反序列化
void deserialize(const std::string& data) {
std::stringstream ss(data);
// 读取基本类型变量
ss.read(reinterpret_cast<char*>(&viewAngleEnum), sizeof(viewAngleEnum));
ss.read(reinterpret_cast<char*>(&bubble), sizeof(bubble));
ss.read(reinterpret_cast<char*>(&isEnglishSystem), sizeof(isEnglishSystem));
ss.read(reinterpret_cast<char*>(&isLap), sizeof(isLap));
ss.read(reinterpret_cast<char*>(&bubbleSize), sizeof(bubbleSize));
// 读取字符串
int strSize;
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
drawSheetPath.resize(strSize);
ss.read(&drawSheetPath[0], strSize);
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
customer.resize(strSize);
ss.read(&customer[0], strSize);
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
selLable.resize(strSize);
ss.read(&selLable[0], strSize);
// 读取整型数组
ss.read(reinterpret_cast<char*>(view), sizeof(view));
// 读取map
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
commonAttrAndVal.clear();
for (int i = 0; i < strSize; ++i) {
std::string key, value;
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
key.resize(strSize);
ss.read(&key[0], strSize);
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
value.resize(strSize);
ss.read(&value[0], strSize);
commonAttrAndVal[key] = value;
}
// 读取静态变量
ss.read(reinterpret_cast<char*>(&strSize), sizeof(strSize));
tempPartName.resize(strSize);
ss.read(&tempPartName[0], strSize);
}
};
// 保存到文件
void saveToFile(const std::string& filename, const InformationUI& info) {
// 序列化
std::string data = info.serialize();
// 写入文件
std::ofstream fout(filename, std::ios::binary);
fout.write(data.c_str(), data.size());
}
// 从文件读取
InformationUI readFromFile(const std::string& filename) {
// 读取文件
std::ifstream fin(filename, std::ios::binary);
std::string data((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
// 反序列化
InformationUI info;
info.deserialize(data);
return info;
}
int main() {
InformationUI info;
info.viewAngleEnum = 1;
info.bubble = 2;
info.isEnglishSystem = 1;
info.isLap = 0;
info.bubbleSize = 3.14;
info.drawSheetPath = "test.dwg";
info.customer = "ABC";
info.selLable = "DEF";
info.view[0] = 0;
info.view[1] = 1;
info.commonAttrAndVal["attr1"] = "value1";
info.commonAttrAndVal["attr2"] = "value2";
InformationUI::tempPartName = "temp";
saveToFile("test.bin", info);
InformationUI info2 = readFromFile("test.bin");
std::cout << info2.viewAngleEnum << std::endl;
std::cout << info2.bubble << std::endl;
std::cout << info2.isEnglishSystem << std::endl;
std::cout << info2.isLap << std::endl;
std::cout << info2.bubbleSize << std::endl;
std::cout << info2.drawSheetPath << std::endl;
std::cout << info2.customer << std::endl;
std::cout << info2.selLable << std::endl;
std::cout << info2.view[0] << std::endl;
std::cout << info2.view[1] << std::endl;
std::cout << info2.commonAttrAndVal["attr1"] << std::endl;
std::cout << info2.commonAttrAndVal["attr2"] << std::endl;
std::cout << InformationUI::tempPartName << std::endl;
return 0;
}
```
在上面的示例中,我们使用`serialize()`函数将`InformationUI`类序列化为二进制格式,在`deserialize()`函数中将二进制格式反序列化为`InformationUI`类。`saveToFile()`函数将序列化后的数据保存到文件中,`readFromFile()`函数从文件中读取数据并反序列化为`InformationUI`类。