我必须在这里使用指针吗?

Posted

技术标签:

【中文标题】我必须在这里使用指针吗?【英文标题】: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 恰好是三角形。 【参考方案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, Triangle,compiles without errors.

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

【讨论】:

这不是一个更好的设计。 class Triangle1class Triangle2,复制代码?绝对是一团糟。

以上是关于我必须在这里使用指针吗?的主要内容,如果未能解决你的问题,请参考以下文章

是迭代器的指针类型转换吗?

我可以使用内存映射文件传递指针吗?

const typedef 和指针的问题(这里必须初始化的才初始化了,不必须的则没有初始化)

我可以将 typedef 结构与指针一起使用吗?

您可以使用指针访问变量以避免直接编辑变量吗? [重复]

超出范围后,在Lambda中设置共享指针