C++ headers 包含顺序,奇怪的行为
C++ headers inclusion order, strange behaviour
我正在编写一些库并希望有一些“可选”class 方法(或只是函数),声明与否,取决于其他库包含。
说,我有一个 class SomeClass
方法 int foo(std::string)
。有时,使用项目所基于的另一个库的 classes 的类似方法也非常有用 - 例如,sf::String
或 wxString
,相应地用于 SFML 或 wxWidgets。
在这种情况下,包括 SFML/System.hpp
甚至更糟,wx/app.hpp
或类似的绝对 不是 一个选项,因为我只想拥有库的方法已经包括在内。所以,我的第一个例子必须(如我所想)工作正常,但它不是:
main.cpp:
#include <SFML/System.hpp> // FIRST, I include SFML base lib in the very first line.
#include <SFML/System/String.hpp>// to be 100% sure, I include SFML string class,
#include "a.h" // and ONLY AFTER that I include my own lib
// so inside the "a.h" file, the sf::String class *must* be already declared
main()
{ SomeClass x;
x.foo("ABC");// error here: "undefined reference to `SomeClass::foo(sf::String)"
}
a.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
class SomeClass
{ public:
#ifdef SFML_STRING_HPP
int foo(sf::String str);// this method is declared, as expected
#endif
};
#endif
a.cpp:
#include "a.h"
#ifdef SFML_STRING_HPP
int SomeClass::foo(sf::String str)
{ return 1;
}
#endif
第一个问题是:为什么? a.cpp
一开始就包含 a.h
,在 a.h
里面声明了 sf::String
,所以为什么在 a.cpp
里面在之后#include "a.h"
它实际上没有声明?
我试图在 a.cpp
文件中的 #endif
指令之前添加 #error OK
,但此错误 未 触发。
我是否遗漏了有关 #include
和 .cpp
/ .h
文件的内容?..
第二个问题是:如何解决或变通?
(是的,我每次都会进行干净的重建,以避免可能出现有关部分更改源的编译器错误,g++ 喜欢它)。
P.S:相同类型的“依赖”方法声明与某些模板 class 完美配合 - 我想,这是因为实现在 .h
文件中,所有内容都在好的关于条件编译。
a.c 包含不包含 的 a.h,因此未定义 SFML_STRING_HPP。通常,要包含的内容是通过编译器 -D 选项设置的。例如-DUSE_SFML_STRING
main.cpp
#include <SFML/System.hpp> // FIRST, I include SFML base lib in the very first line.
#include "a.h" // and ONLY AFTER that I include my own lib
// so inside the "a.h" file, the sf::String class *must* be already declared
main()
{ SomeClass x;
x.foo("ABC");// error here: "undefined reference to `SomeClass::foo(sf::String)"
}
a.h
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
#ifdef USE_SFML_STRING
#include <SFML/System/String.hpp>
#endif
class SomeClass
{ public:
#ifdef SFML_STRING_HPP
int foo(sf::String str);// this method is declared, as expected
#endif
};
#endif
我正在编写一些库并希望有一些“可选”class 方法(或只是函数),声明与否,取决于其他库包含。
说,我有一个 class SomeClass
方法 int foo(std::string)
。有时,使用项目所基于的另一个库的 classes 的类似方法也非常有用 - 例如,sf::String
或 wxString
,相应地用于 SFML 或 wxWidgets。
在这种情况下,包括 SFML/System.hpp
甚至更糟,wx/app.hpp
或类似的绝对 不是 一个选项,因为我只想拥有库的方法已经包括在内。所以,我的第一个例子必须(如我所想)工作正常,但它不是:
main.cpp:
#include <SFML/System.hpp> // FIRST, I include SFML base lib in the very first line.
#include <SFML/System/String.hpp>// to be 100% sure, I include SFML string class,
#include "a.h" // and ONLY AFTER that I include my own lib
// so inside the "a.h" file, the sf::String class *must* be already declared
main()
{ SomeClass x;
x.foo("ABC");// error here: "undefined reference to `SomeClass::foo(sf::String)"
}
a.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
class SomeClass
{ public:
#ifdef SFML_STRING_HPP
int foo(sf::String str);// this method is declared, as expected
#endif
};
#endif
a.cpp:
#include "a.h"
#ifdef SFML_STRING_HPP
int SomeClass::foo(sf::String str)
{ return 1;
}
#endif
第一个问题是:为什么? a.cpp
一开始就包含 a.h
,在 a.h
里面声明了 sf::String
,所以为什么在 a.cpp
里面在之后#include "a.h"
它实际上没有声明?
我试图在 a.cpp
文件中的 #endif
指令之前添加 #error OK
,但此错误 未 触发。
我是否遗漏了有关 #include
和 .cpp
/ .h
文件的内容?..
第二个问题是:如何解决或变通?
(是的,我每次都会进行干净的重建,以避免可能出现有关部分更改源的编译器错误,g++ 喜欢它)。
P.S:相同类型的“依赖”方法声明与某些模板 class 完美配合 - 我想,这是因为实现在 .h
文件中,所有内容都在好的关于条件编译。
a.c 包含不包含
main.cpp
#include <SFML/System.hpp> // FIRST, I include SFML base lib in the very first line.
#include "a.h" // and ONLY AFTER that I include my own lib
// so inside the "a.h" file, the sf::String class *must* be already declared
main()
{ SomeClass x;
x.foo("ABC");// error here: "undefined reference to `SomeClass::foo(sf::String)"
}
a.h
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
#ifdef USE_SFML_STRING
#include <SFML/System/String.hpp>
#endif
class SomeClass
{ public:
#ifdef SFML_STRING_HPP
int foo(sf::String str);// this method is declared, as expected
#endif
};
#endif