【问题标题】:Do I _have to_ use a pointer here?我必须在这里使用指针吗?
【发布时间】:2011-06-11 17:06:22
【问题描述】:

我一次又一次地遇到这个问题,而且我总是不得不使用前向声明和指针来解决它。

C++ 需要变通方法 让对象协作似乎是错误的。有什么方法可以编译而不使 Mesh* 成为 Shape 类中的指针(或者,将 vector<Tri> 转换为 vector<Tri*>

形状.h

#ifndef S
#define S

#include "Mesh.h"
//class Mesh ; //delete line above, uncomment this to make it work
class Shape // a mathematical shape
{
    Mesh mesh ; // the poly mesh repr' this math shape
    //Mesh *mesh ; // make it work

    // a shape must be intersectable by a ray
    //virtual Intersection intersects( const Ray& ray )=0 ;
} ;

#endif

Mesh.h

#ifndef M
#define M

#include <vector>
using namespace std;
#include "Triangle.h"

struct Mesh
{
    vector<Triangle> tris ; // a mesh is a collection of triangles
} ;

#endif

三角形.h

#ifndef T
#define T
#include "Shape.h"
class Triangle : public Shape
{
    // a triangle must be intersectable by a ray
    // a triangle's mesh is simple but it is still a mesh (1 poly)
} ;
#endif

【问题讨论】:

  • 编译器必须知道类的所有成员的大小。否则它无法为对象分配适当的空间。
  • @Bo: sizeof(vector&lt;Triangle&gt;) 不一定依赖于sizeof(Triangle)
  • 我不明白。您有一个形状,它拥有一个由三角形列表组成的网格,这些形状每个都拥有一个由三角形列表组成的网格?
  • @Andre:如果允许某些列表为空,则可以使用,而网格/形状似乎并非如此。
  • 所以,你想要的是每个Triangle,通过其基类的mesh数据成员,包含一个Triangle的向量。大概您希望这个向量的大小为 1,但它到底包含什么?一个三角形,它有自己的向量等。即使你用指针打破循环依赖,你也无法定义顶点的坐标。所以定义仍然是圆形的,并没有真正定义三角形。通常的解决方法是不从 Shape 继承 Triangle - 使 Triangle 三个点,而网格大小为 1 的 Shape 恰好是三角形。

标签: c++ pointers object


【解决方案1】:

您似乎基本上是在说 Shape 是使用 Mesh 实现的,而 Mesh 是使用形状(特别是三角形)实现的。这显然没有意义。

【讨论】:

  • @Neil:我认为他选择了一个坏例子。在很多情况下,这种包含是合适的,并最终以一个空的子对象集合终止。
  • @Ben 这对我来说比 OP 所做的更没有意义。
  • @Neil:想想目录树(在文件系统上,它实际上是一棵树,不允许硬链接)。每个节点都有一组子节点。最终,您必须到达子集合为空的叶节点。
  • @Ben 对不起,这不会让我的船浮起来。 OP的数据结构不是一棵树,一棵树只由一种类型——节点组成。
  • @Neil:OP 的数据结构是一棵树(如果你只看结构而忽略名称)。而目录树既有目录又有文件,有两种节点。
【解决方案2】:

您不能将不完整的类型声明为成员。

当你前向声明一个类型时,编译器只知道这个类型存在;它对大小或成员或方法一无所知。它被称为不完整类型

除非包含Mesh.h,否则MeshIncomplete type,并且您不能将不完整类型声明为成员。

但是,您可以将指向 Incomplete type 的指针作为成员,因此如果您转发声明 class Mesh,则您的成员必须是 Mesh*

总之,你说的是对的。

【讨论】:

  • @bobobobo:刚刚完成编辑它可以是一个指针并注意到你的评论:)
  • 这个答案是正确的,但无关紧要。 Mesh 没有任何类型为 Triangle 的成员。
  • Triangle 的向量需要包含 Triangle.h 标头
【解决方案3】:

它在没有指针的情况下对我有用(当然,std::vector 内部使用了指针)。你只需要仔细分析你的依赖关系。 Triangle 继承 Shape,因此 Shape 的定义高于 Triangle 的定义。 Shape 包含 Mesh,因此 Mesh 的定义在 Shape 之前。这给出了顺序:Mesh, Shape, Trianglecompiles without errors.

当然,一些网格必须有空向量,因为向量内的每个三角形本身都需要一个网格。

【讨论】:

    【解决方案4】:

    你总是做对了,没有其他方法可以做到。

    【讨论】:

      【解决方案5】:

      您可以根据不同的、简单的低级三角形结构来定义您的网格。您的高级三角形“形状”可以与低级三角形共享碰撞代码,同时仍然是一个单独的类。因此Mesh.h 不需要包含Triangle.h。这将打破你的循环依赖,让你在 Shape 类中有一个 Mesh 成员。

      【讨论】:

      • 这不是一个更好的设计。 class Triangle1class Triangle2,复制代码?绝对是一团糟。
      猜你喜欢
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多