在单独的 class 方法中使用它会使程序崩溃

Using this in a seperate class methods crashes the program

我在从直接父 Base class 调用方法时遇到挑战,但我可以轻松调用 Base class 的父级中的方法。为了澄清我的意思,这里是代码:

首先是opencascade库的结构classes:

class TopoDS_Shape 
{
public:
   //..... a lot of methods like Closed(), Oriantable(), etc
};

class TopoDS_Face : public TopoDS_Shape
{
   TopoDS_Face(); // implementation is like TopoDS_Face::TopoDS_Face(){}
}

在我的代码中有两种类型的拓扑面平面 (ModelFace class) 和非平面 (ModelBend class)。这两个面共享 MFace class 中定义的 6 个属性,但只有 ModelBend class 具有其自己的附加属性,因此我将系统设计如下

M脸class:

class MFace : public TopoDS_Face 
{
 FaceID mFaceID;
 PlaneType mPlaneType;
 FaceType mFaceType;
 gp_Pnt mFaceNormal;

 public:
  void ModelFace::extractEdges()
  {
    for (TopExp_Explorer edgeEx((*this), TopAbs_EDGE); edgeEx.More(); edgeEx.Next())
    {
      TopoDS_Edge edge = TopoDS::Edge(edgeEx.Current());
      ModelEdge edgex(edge);

      addEdge(edgex);
    }
  }

  // Setters and getters

  // The OpenCascade Lib has a non-template method similar to this for converting a  
  // TopoDS_Shape to a face/edge/vertex/wire
  template<typename T>
  static T& toFace(TopoDS_Face& shape)
  {
    return *(T*) &shape;
   }
};

模特脸class:

 class ModelFace : public MFace
 {
   ModelFace(); // implementation is like ModelFace::ModelFace(){}

   void ModelFace::init(FaceID faceID) // WORKS LIKE A CHARM!!!
   { 
     setFaceId(faceID);

     std::cout << "ID : " << getFaceId() << '\n';

     if (Closed()) {
      std::cout << "Orr : " << Orientable() << '\n';
     }
   }

 };

ModelBend class:

class ModelBend : public MFace
 {
   // Bend attributes : angles, radius, etc
   ModelBend(); // implementation is like ModelBend::ModelBend(){}

   // Setters and getters
   // methods for computations

};

用法:有一个模型 class 表示 CAD 模型并存储其所有拓扑 ModelFace/ModelBend 数据。此 class 以 TopoDS_Shape 的形式获取拓扑数据,并 class 在 assignAttributes() 中对其进行处理,如下所示:

  void Model::assignFaceAttributes(const FaceID faceID, TopoDS_Shape& aShape)
  {
    // TODO : set the face attributes
    TopoDS_Face pTopoDSFace = TopoDS::Face(aShape);
    Standard_Real curvature = computeCurvature(pTopoDSFace);

    if (curvature == 0.0){

      std::cout << "Face" << '\n';

      // Convert TopoDS_Face to ModelFace
      ModelFace& pModelFace = MFace::toFace<ModelFace>(pTopoDSFace);

      // This code work well : calls Orientable() in the TopoDS_Shape class
      std::cout << "Orientable? : " << pModelFace.Orientable() << '\n';

      // Works well
      pModelFace.init(faceID);

      // **PROGRAM CRASHES HERE!!!!!!!!!!!!!!**
      pModelFace.extractEdges();

      //...

    } else {
      // .....
      std::cout << "Bend" << '\n';

      // Convert TopoDS_Face to ModelBend
      ModelBend& pModelFace = MFace::toFace<ModelBend>(pTopoDSFace);

      //...
    }

    addFace(&pModelFace);

  }

当我 运行 程序在 assignAttributes() 中调用 pModelFace.extractEdges() 时崩溃,但是当我将 extractEdges() 方法中的 for 循环复制到 init() 方法工作正常。

我的 OOD/OOP 不是很好。能否请您帮我解决问题以及这种行为的原因。提前致谢。

这看起来与您自己的其他问题重复:

TopoDS_Shape 没有虚拟方法(包括没有虚拟析构函数)并且在 OCCT 中通过复制 进行管理(例如,不是动态的分配)。像在 MFace 中那样添加 class 字段只有当你像 MFace 一样存储对象时才会起作用 - 否则你只是将内存中较小的对象 TopoDS_Shape 转换为较大的 MFace 导致 reading/writing 内存未初始化并崩溃。

你的 MFaceTopoDS_Face 之间的主要区别是 TopoDS_Face 定义 没有新的 class 字段 也没有虚拟方法, 它允许别名 TopoDS_ShapeTopoDS_Face 而没有副作用。

例如:

void parseMFace (TopoDS_Shape& theFace)
{
  MFace* anMFace = (MFace* )&theFace;
  anMFace->doSomething();
}

int main()
{
  MFace anMFace;
  parseMFace (anMFace); // unsafe, but should work
  TopoDS_Face aTFace;
  parseMFace (aTFace); // will crash
  TopoDS_Compound aComp;
  BRep_Builder().MakeCompound (aComp);
  BRep_Builder().Add (aComp, anMFace); // here MFace will be truncated to TopoDS_Shape
  for (TopoDS_Iterator aFaceIter (aComp); aFaceIter.More(); aFaceIter.Next()
  {
    TopoDS_Face& aTFace2 = TopoDS::Face (aFaceIter.Value());
    parseMFace (aTFace2); // will crash, because TopoDS_Compound does not store MFace 
  }
  std::vector<MFace> anMFaces;
  anMFaces.push_back (anMFace);
  parseMFace (anMFaces[0]); // OK, but unsafe
}