31

MeshとMeshListの2つのクラスがあります。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):「メッシュ」の宣言を参照してください
  • 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を最初に、サードパーティのヘッダーを2番目に、独自のミドルウェアスタックを3番目に、現在のプロジェクトに4番目を、現在のライブラリに5番目を含めます。このように、競合がある場合、エラーがあなたのヘッダーを指していることを願っています。

  • クラスの内容のpublic前に内容を置きます。privateクラスのクライアントは、パブリックインターフェイスのみに関心があり、アクセスする前に、すべてのダーティな実装の詳細を確認する必要はありません。

于 2012-04-27T06:38:36.443 に答える