在单独的 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 内存未初始化并崩溃。
你的 MFace
和 TopoDS_Face
之间的主要区别是 TopoDS_Face
定义 没有新的 class 字段 也没有虚拟方法, 它允许别名 TopoDS_Shape
到 TopoDS_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
}
我在从直接父 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 内存未初始化并崩溃。
你的 MFace
和 TopoDS_Face
之间的主要区别是 TopoDS_Face
定义 没有新的 class 字段 也没有虚拟方法, 它允许别名 TopoDS_Shape
到 TopoDS_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
}