建筑墙体与天花板平面数据存储及类结构优化咨询
virtual ~Wall() = 0; // Setters ... // Getters ... // Pure Virtual Functions virtual void setHeight(int newHeight) = 0; virtual void setLength(int newLength) = 0; virtual int getArea() const = 0; virtual int getHeight() const = 0; virtual int getLength() const = 0;
};
class PentagonWall : public Wall {
private:
Quadrilateral* Quad1;
Quadrilateral* Quad2;
public:
// Constructors
...
~PentagonWall(); void setHeight(int newHeight) override {} void setLength(int newLength) override {} int getArea() const override { return this->Quad1->getArea() + this->Quad2->getArea(); } int getHeight() const override { return -1; } int getLength() const override { return this->Quad1->rect.Length + this->Quad2->rect.Length; } Quadrilateral* getQuad1() { return this->Quad1; } Quadrilateral* getQuad2() { return this->Quad2; }
};
class RectangleWall : public Wall {
private:
Rectangle* Square;
public:
RectangleWall();
RectangleWall(int prev, int next);
~RectangleWall();
void setHeight(int newHeight) override {
this->Square.Height = newHeight;
}
void setLength(int newLength) override {
this->Square.Length = newLength;
}
int getArea() const override {
return this->Square.Height * this->Square.Length;
}
int getHeight() const override {
return this->Square.Height;
}
int getLength() const override {
return this->Square.Length;
}
};
### 形状结构体 ```cpp struct Shape { Shape() {} virtual int getArea() = 0; }; struct Ceiling : Shape { int Orientation; int Pitch; int FootPrintArea; Ceiling() : Orientation(0), Pitch(0), FootPrintArea(0) {} Ceiling(int initOri, int initPitch, int initFPArea) : Orientation(initOri), Pitch(initPitch), FootPrintArea(initFPArea){} int getArea() override { if (Pitch == 0) return this->FootPrintArea; return this->FootPrintArea * OtEnum::PITCH_TO_MULTIPLIER[this->Pitch]; } }; struct Rectangle : Shape { int Length; int Height; // Constructors ... int getArea() override { return this->Length * this->Height; } }; struct Triangle : Shape { int Base; int Height; // Constructors ... int getArea() override { return (this->Base * this->Height) / 2; } }; struct Quadrilateral : Shape { Rectangle rect; Triangle tri; Quadrilateral() : rect(0, 0), tri(0, 0) {} Quadrilateral(Rectangle newRect, Triangle newTri) : rect(newRect.Length, newRect.Height), tri(newTri.Base, newTri.Height) {} int getArea() override { return rect.getArea() + tri.getArea(); } };
Roof结构体
struct Roof { Ceiling* Ceil; Wall* HingeWall; Quadrilateral* Quad1; Quadrilateral* Quad2; Rectangle* BackRect; Wall* BackWall; Roof(Wall* newHingeWall); Roof(); };
现有工作逻辑
每个Roof对应2D绘图中下方的墙体,以此确定Quadrilateral的长度;更新Roof的Pitch时,对应Quadrilateral的Triangle高度会更新;更新Roof铰接墙体高度时,对应Quadrilateral的Rectangle高度会更新,操作复杂度为O(1),仅初始化时需设置Roof类指针(参考屋顶结构示意)。当前通过遍历天花板平面,结合线条位置、墙体是否铰接等条件分配HingeWall、Quad1、Quad2、BackWall,功能可正常运行,但设计不够优雅,需优化。
1. 消除冗余指针与所有权混乱
- 现有Roof与PentagonWall均持有Quad1/Quad2指针,易出现数据同步问题,需调整关联逻辑:让PentagonWall通过Roof获取Quadrilateral数据,或由Roof统一管理Quad实例,避免重复持有。
- 替换所有裸指针为智能指针(
std::unique_ptr/std::shared_ptr),明确内存所有权,避免内存泄漏与野指针问题。
2. 职责单一化重构
- Roof职责聚焦:Roof应作为天花板坡度、铰接墙体关联的逻辑载体,而非直接存储Quadrilateral实例。PentagonWall的面积计算改为实时推导:根据Roof的坡度、铰接墙高度、自身长度等参数,动态计算Quadrilateral的面积,避免存储静态数据导致的同步问题。
- 修复Wall接口契约:PentagonWall的
setHeight/setLength空实现违反里氏替换原则,需改为:若为铰接墙关联的PentagonWall,setHeight实际触发Roof更新铰接墙高度;或让PentagonWall的高度直接从关联的Roof/铰接墙获取,移除空实现。
3. 简化关联初始化逻辑
- 设计
RoofBuilder类,专门负责2D线条解析、墙体类型判断、Roof与墙体的关联绑定,把遍历天花板平面分配关联的复杂逻辑从业务代码中抽离,让主逻辑更清晰。 - 创建Roof时直接传入所需的关联对象(铰接墙、相邻PentagonWall、后墙等),避免后续手动遍历分配。
4. 强化接口契约与类型安全
- 替换PentagonWall中
getHeight()返回的魔法值-1,改用std::optional<int>或新增hasFixedHeight()方法,明确区分无固定高度的墙体类型,避免调用者处理歧义。 - 将
OtEnum::PITCH_TO_MULTIPLIER封装为Ceiling的静态成员或方法,减少对全局枚举的依赖,提升封装性。
5. 形状类优化
- 将Quadrilateral改为计算类:无需存储Rectangle与Triangle实例,而是根据输入参数(铰接墙高、坡度、长度)实时计算面积,减少内存占用与数据同步成本。
- 将Shape类的
getArea()返回类型从int改为double,提升坡度计算场景下的精度。
内容的提问来源于stack exchange,提问作者user18900864

