2016-12-08 9 views
0

Я знаю, что это было задано несколько раз, но ответы, похоже, не решают этого.C++ Включить защитные устройства

У меня есть два файла.

main.cpp

#include <irrlicht\irrlicht.h> 

#include <vector> 
#include <string> 
#include <iostream> 

#include "Scene.h" 
#include "Camera.h" 
#include "Gui.h" 

irr::IrrlichtDevice* device; 
irr::video::IVideoDriver* driver; 

int main() { 
device = irr::createDevice(irr::video::EDT_SOFTWARE, irr::core::dimension2d<irr::u32>(640, 480), 16, false, false, false, 0); 

if (!device) 
    return 1; 

device->setWindowCaption(L"NeoTrap"); 
driver = device->getVideoDriver(); 
sceneManager = device->getSceneManager(); 
GUIEnvironment = device->getGUIEnvironment(); 

//Testing 
Mesh* ground = new Mesh(); 
//Testing 

while (device->run()) { 
    driver->beginScene(true, true, irr::video::SColor(255, 120, 102, 136)); 

    sceneManager->drawAll(); 
    GUIEnvironment->drawAll(); 

    driver->endScene(); 
} 

device->drop(); 
return 0; 
} 

Scene.h

#ifndef _SCENE_HEADER_ 
#define _SCENE_HEADER_ 

irr::scene::ISceneManager* sceneManager; 

struct Mesh { 
public: 
Mesh(); 

private: 
}; 

class Scene { 
public: 
Scene(); 

private: 

}; 

#endif 

То, что я пытаюсь сделать, это объявили переменную в Scene.h и определить его внутри главной функции. Я не уверен, что я не понимаю, включая охранников, но я получаю странные ошибки:

'irr': не является именем класса или пространства имен синтаксическая ошибка: отсутствует ';' перед '*' отсутствующий спецификатор типа - int. Примечание: C++ не поддерживает по умолчанию-ИНТ

, но когда я перехожу следующую строку обратно в main.cpp файл

irr::scene::ISceneManager* sceneManager; 

программа компиляции. Когда я не могу объявить его в scene.h и установить значение из основной функции?

+0

В какой файл 'определен IRR :: сцена :: ISceneManager'? – tmpearce

+0

Scene.h, на самом верху. – Kurieita

+0

Нет, это то, где вы объявляете переменную типа указатель-на-тот. Где этот ** тип ** (класс или структура) определен? – tmpearce

ответ

3

Лучше не объявлять переменные в заголовках. Он заканчивается очень далеко, а не потому, что каждый файл, который включает заголовок, сделает их собственный sceneManager. Когда компоновщик приходит вместе, чтобы скомпоновать программу, он может найти десятки sceneManager s с одинаковым требованием быть реальным sceneManager, отбросить руки вверх с отвращением и скрыть сообщения об ошибках по всей консоли.

В scene.h добавить

#include <irrlicht\irrlicht.h> 

на вершине, чтобы объявить все биты и качается из Irrlicht так, что они доступны в scene.h.

Затем измените

irr::scene::ISceneManager* sceneManager; 

в

extern irr::scene::ISceneManager* sceneManager; 

extern сообщает компилятор, что sceneManager существует и хранение будет выделено где-то еще. Компилятор улыбается и продолжает, оставляя сортировку, где тот, истинный sceneManager, является компоновщиком.

Наконец, положить

irr::scene::ISceneManager* sceneManager; 

в main.cpp, чтобы выделить память, так что линкер имеет sceneManager найти.

Documentation on extern

Рекомендован чтение: When to use extern in C++

+0

Очень красивый и очень быстрый ответ. Большое спасибо +1 за вас. :) – Kurieita

+0

Краткий и пояснительный. Хороший ответ, +1. – frasnian

3

Вы заявляете, что sceneManager имеет тип irr::scene::ISceneManager*, но пространство имен irr не существует, когда вы объявляете эту переменную. Добавьте include в заголовочный файл, который объявляет это пространство имен перед объявлением переменной.

После этого вам нужно объявить sceneManager в качестве заголовка extern, чтобы каждый блок компиляции, содержащий этот заголовок, не создал свой собственный экземпляр переменной. Тогда, поскольку это extern, вы также захотите его обновить (без extern) в main.cpp.

Смежные вопросы