C ++不会让我交朋友

时间:2012-04-27 01:17:12

标签: c++ visual-c++

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

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

Mesh.cpp

#include "Mesh.h"

MeshList.h

#ifndef _MESH_LIST_H
#define _MESH_LIST_H

#include "Mesh.h"


class MeshList
{

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

MeshList.cpp

#include "MeshList.h"

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

我收到这些错误:

MeshList.h(第11行)

  • 错误C2143:语法错误:缺少';'在'*'
  • 之前
  • 错误C4430:缺少类型说明符 - 假定为int。注意:C ++没有 支持default-int
  • 错误C4430:缺少类型说明符 - 假定为int。注意:C ++没有 支持default-int

  • 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 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分: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;
}

答案 2 :(得分:6)

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

解决方案来了:

MeshList.h

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

MeshList.cpp

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

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

*mesh->vboHandle_ = 4;

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

mesh->vboHandle_ = 4; // <-- no leading asterisk

答案 3 :(得分: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优先,第三方标题第二,您自己的中间件堆栈第三,当前项目包括第四,当前库包括第五。这样,如果存在冲突,希望错误将指向您的标题。

  • public内容放在课程中的private内容之前。该类的客户端只关注公共接口,不需要让它们在所有脏的实现细节之前进行处理。