31

我有两个类,Mesh 和 MeshList。我希望 MeshList 具有可以更改 Mesh 私有成员的功能。但它不会编译,我不知道为什么。这是我的代码。

网格.h

#ifndef _MESH_H
#define _MESH_H

#include "MeshList.h"
#include <iostream>

class Mesh
{
private:
    unsigned int vboHandle_;
    friend void MeshList::UpdateVBOHandle();
public:
    inline void Out() {std::cout << vboHandle_;}
};
#endif

网格.cpp

#include "Mesh.h"

网格列表.h

#ifndef _MESH_LIST_H
#define _MESH_LIST_H

#include "Mesh.h"


class MeshList
{

public:
    Mesh *mesh; //Line 11 Error
    void UpdateVBOHandle();
};
#endif

网格列表.cpp

#include "MeshList.h"

void MeshList::UpdateVBOHandle()
{
    *mesh->vboHandle_ = 4;
}

我收到这些错误:

MeshList.h(第 11 行)

  • 错误 C2143:语法错误:缺少“;” 前 '*'
  • 错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数
  • 错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数

  • mesh.h(11):错误 C2653:“MeshList”:不是类或命名空间名称

  • meshlist.cpp(5):错误 C2248:“Mesh::vboHandle_”:无法访问在“Mesh”类中声明的私有成员
  • mesh.h(10) : 参见 'Mesh::vboHandle_' 的声明
  • mesh.h(8) : 参见“Mesh”的声明
  • meshlist.cpp(5) : 错误 C2100: 非法间接
4

4 回答 4

9

当您编译Mesh.cpp时,它包括Mesh.h,其中包括MeshList.h,开始包括但由于现在已定义Mesh.h而提前停止。_MESH_H然后(返回MeshList.h)有一个对Mesh-- 的引用,但尚未声明。因此,例如,您的 C2143 错误。

于 2012-04-27T01:21:37.470 回答
7

其他答案中解释了循环依赖关系......

解决方案来了:

MeshList.h

  • 替换#include "Mesh.h"为前向声明class Mesh;(此处不需要包含,因为您只声明了指向网格的指针)

MeshList.cpp

  • 添加#include "Mesh.h"到您的包含(您需要声明,因为您使用网格)

您提到的最后一个编译错误是另一个问题:

*mesh->vboHandle_ = 4;

mesh是一个指针。您的代码选择该成员vboHandle_并尝试取消引用它(失败)。我想你的意思是:

mesh->vboHandle_ = 4; // <-- no leading asterisk
于 2012-04-27T08:45:51.210 回答
6

这是因为你已经#include "MeshList.h"在文件中了Mesh.h,所以文件MeshList.h会先被编译,而类Mesh还没有被声明。为此,编译器会认为Mesh错误行中的变量名之前没有类型,因此出现错误。

这是制作friend成员函数的示例:

#include <iostream>


class foo;

class bar
{
public:
    void barfunc(foo &f);
};

class foo
{
private:
    friend void bar::barfunc(foo &f);
    int i;
public:
    foo()
    {
        i = 0;
    }
    void printi()
    {
        std::cout << i << '\n';
    }
};

void bar::barfunc(foo &f)
{
    f.i = 5;
}


int main()
{
    foo f;
    bar b;
    b.barfunc(f);
    f.printi();
    return 0;
}
于 2012-04-27T01:24:31.777 回答
4

问题:包含中的循环依赖项。不幸的是,错误消息不太理想。


解决方案:如果您与整个类而不是单个函数成为朋友,那么您可以使用类的前向声明来打破循环。

// Mesh.h
#ifndef _MESH_H
#define _MESH_H

#include <iostream>

class MeshList;

class Mesh
{
private:
    unsigned int vboHandle_;
    friend class MeshList;
public:
    inline void Out() {std::cout << vboHandle_;}
};
#endif

一些(主观)指南:

  • 以与您在损坏时更改它的能力相反的顺序包含内容,即:首先是 STL,其次是 3rd 方标头,第三是您自己的中间件堆栈,当前项目包括第四,当前库包括第五。这样,如果发生冲突,希望错误将指向您的标题。

  • 把东西放在课堂上的public东西之前。private类的客户只关心公共接口,不需要让他们在获得它之前遍历所有肮脏的实现细节。

于 2012-04-27T06:38:36.443 回答