Ошибка компилятора VisualC ++ C3646: неизвестный спецификатор переопределения

Я пытаюсь написать простой движок DirectX11, но продолжаю получать эту странную ошибку и не могу найти проблему: я определяю класс Terrain и класс Mesh и #include класс Mesh в классе Terrain:

определение класса Terrain:

// Terrain.h
#pragma once

#include "Noise.h"#include "Mesh.h"
class Terrain
{
public:
Terrain(float width, float depth, int numVerticesW, int numVerticesD);
~Terrain();
float GetHeight(float x, float z);
void Draw();
private:
Mesh mMesh;                     // I get the error on this line
Noise mNoiseGenerator;
std::vector<float> mHeights;
void CreateTerrain(float width, float depth, int numVerticesW, int numVerticesD);
float ComputeHeight(float x, float z, float startFrequency, float startAmplitude, float persistence, int octaves);
};

и определение класса Mesh:

// Mesh.h
#pragma once

#include <d3d11.h>
#include <vector>
#include "Game.h"
class Mesh
{
public:
Mesh();
~Mesh();
template <typename T, unsigned int N>
void LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic = false);
void LoadIndexBuffer(std::vector<unsigned int> indices);
void SetVertexCount(unsigned int vertexCount);
void Bind();
void Draw();
private:
std::vector<ID3D11Buffer*> mVertexBuffers;
std::vector<unsigned int> mStrides;
ID3D11Buffer *mIndexBuffer;
unsigned int mVertexCount;
};template <typename T, unsigned int N>
void Mesh::LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic)
{
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_IMMUTABLE;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.ByteWidth = sizeof(T[N]) * size;
bufferDesc.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA bufferData = {};
bufferData.pSysMem = data;

ID3D11Buffer *buffer;
Game::GetInstance()->GetDevice()->CreateBuffer(&bufferDesc, &bufferData, &buffer);
mVertexBuffers.push_back(buffer);
mStrides.push_back(sizeof(T[N]));
}

Когда я компилирую код, я получаю:

Severity    Code    Description Project File    Line    Suppression State
Error   C3646   'mMesh': unknown override specifier DirectX11 engine 0.3    c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h  14
Severity    Code    Description Project File    Line    Suppression State
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    DirectX11 engine 0.3    c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h  14

Я искал в Интернете, но большинство результатов показывают пропущенные точки с запятой или циклические проблемы с включением, но я не могу их найти.

РЕДАКТИРОВАТЬ
Я обнаружил проблему, но не могу объяснить, почему мое решение работает:
следуя дереву включения:
Terrain.h -> Mesh.h -> Game.h -> Renderer.h -> Terrain.h

устранение #include «Terrain.h» (поскольку я просто объявляю указатели Terrain * внутри класса) и добавление его в Terrain.cpp, похоже, решает проблему.
Так что, должно быть, речь идет о круговом включении, но разве я не должен быть защищен от этого с помощью защиты заголовка / включения?

1

Решение

Ваша проблема в том, что #pragma once предотвращает только двойное включение. То есть это делает следующее безопасным (упрощенным, чтобы сделать это очевидным):

// Terrain.cpp
#include "Terrain.h"#include "Terrain.h"

Это не решает круговое включение, которое гораздо сложнее решить автоматически. С двойным включением понятно, кто из них первый. Но у круга нет начала.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]