2015-06-27 2 views
0

я получаю необъявленную ошибку идентификатора (C2065 на vs2013) на моем проекте, мне удалось воспроизвести проблему в примере коде ниже:Как решить этот необъявленный идентификатор

foo.h:

#pragma once 

#include "bar.h" 

class Foo 
{ 

public: 
    inline void doStuff() { someFunction(); } 

}; 

bar.h:

#pragma once 

#include <map> 

#include "foo.h" 

extern std::map<const char*, Foo> myMap; 

void someFunction(); 

bar.cpp:

#include "bar.h" 

std::map<const char*, Foo> myMap; 

void someFunction() 
{ 

} 

main.cpp:

#include "foo.h" 

int main() 
{ 
    Foo foo; 
    foo.doStuff(); 
    return 0; 
} 

При создании на Visual Studio Express 2013, это дает следующие ошибки:

ошибка C2065: 'Foo': необъявленный идентификатор

ошибка C2923: «STD :: Карта»: 'Foo' не является допустимым типом аргумента шаблона для параметра '' _Ty

ошибка C3861: 'SomeFunction': идентификатор не найден

В чем проблема и как ее можно решить?

ответ

4

У вас есть проблема с круговым определением. Обратите внимание, что foo.h включает bar.h и bar.h включает foo.h. Это не может работать, потому что это означает, что ни одно определение не может быть выполнено до тех пор, пока не будет выполнено другое определение. Единственный способ устранить эту проблему - изменить структуру, чтобы в одном из заголовков не был #include другой заголовок.

+1

И передать ссылку классу в тот, который вы удаляете из include. – Robinson

+0

Благодарим за совет, решив проблему, переместив #include из заголовка в файл cpp. –

0

Проблема вызвана круговой зависимостью между foo.h и bar.h. Он может быть разрешен с использованием любого из следующих методов, о которых я могу думать.

Метод 1

  1. Используйте опережающее объявление класса Foo в bar.h.
  2. Не использовать #include "foo.h" в bar.h.

foo.h:

#pragma once 

#include "bar.h" 

class Foo 
{ 

public: 
    inline void doStuff() { someFunction(); } 

}; 

bar.h:

#pragma once 

#include <map> 

// #include "foo.h" 
class Foo; 

extern std::map<const char*, Foo> myMap; 

void someFunction(); 

Метод 2

  1. Создать foo.cpp и добавьте его в проект.
  2. Переместить реализацию Foo::doStuff() в foo.cpp.
  3. Не использовать #include "bar.h" в foo.h.

foo.h:

#pragma once 

class Foo 
{ 

public: 
    void doStuff(); 

}; 

bar.h:

#pragma once 

#include <map> 

#include "foo.h" 

extern std::map<const char*, Foo> myMap; 

void someFunction(); 

Foo.CPP:

#include "foo.h" 
#include "bar.h" 

void Foo::doStuff(){ someFunction(); } 

Метод 3

использовать оба Метод 1 и Способ 2.

foo.h:

#pragma once 

class Foo 
{ 

public: 
    void doStuff(); 

}; 

bar.h:

#pragma once 

#include <map> 

// #include "foo.h" 
class Foo; 

extern std::map<const char*, Foo> myMap; 

void someFunction(); 

foo.cpp:

#include "foo.h" 
#include "bar.h" 

void Foo::doStuff(){ someFunction(); } 

я настоятельно рекомендуется использовать метод . В качестве общего руководства, лучше использовать в объявлениях заголовков, если вам не нужно полное определение класса .

+0

Это не сработает, bar.h должен знать о классе Foo. –

+0

Речь идет о худшем способе решения круговых зависимостей. –

+0

@LightnessRacesinOrbit, соглашайтесь с вашим комментарием. Не удалось вернуться к исправлению ответа до сих пор. –

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