我必须在这里使用指针吗?
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<Triangle>)
不一定依赖于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
,否则Mesh
是Incomplete 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 Triangle1
和 class Triangle2
,复制代码?绝对是一团糟。以上是关于我必须在这里使用指针吗?的主要内容,如果未能解决你的问题,请参考以下文章