2

这个让我挠头太久了。

我在标题 test.h 中有以下内容:

inline void anything(){
std::cout<<" anything "<<ii;
}

然后我有啊,其中包括test.h:

class Fooness{
public: 
Fooness(){
    anything(); //compiler reports "use of undeclared identifier"
    };
};

但是,如果我只是将函数定义移动到 a.cpp:

Fooness::Fooness(){
anything();
}

有用。a.cpp 包含 test.h 其中包含 ah 为什么anything()只在 a.cpp 中可见而不是啊?

4

2 回答 2

2

正如您在评论中指出的那样,您包括a.h在内test.h反之亦然由于循环依赖(也称为交叉包含),这会引入错误,因为函数和类“未定义” 。

在您的情况下,当.cpp文件包含test.h,它首先包含a.h然后定义函数,这显然不是您想要的,因为在处理时,未定义。anything();a.hanything()

在编译包含test.h(before a.h) 的单元时,您的代码会扩展为与此类似的内容,该单元本身首先包含a.h其他任何内容:

/* INCLUDED FROM a.h */
class Fooness{
public: 
Fooness(){
    anything();
    };
};

inline void anything() {
    ....
}

如您所见,使用时没有anything()定义。但是,如果一个编译单元包含a.h(before test.h),而它本身包含test.h,它会扩展为如下内容:

/* INCLUDED FROM test.h */
inline void anything() {
    ....
}

class Fooness{
public: 
Fooness(){
    anything();
    };
};

所以顺序是正确的。

为了使其在这两种情况下都能正常工作,您可以在包含之前进行前向声明anything()test.ha.h

test.h的更正版本

#ifndef TEST_H
#define TEST_H

void anything(); // forward-declaration

#include "a.h"   // <-- this is important to be *below* the forward-declaration

inline void anything() {
    ....
}

// more stuff

#endif

然后,当包含test.h(before a.h) 时,它会扩展为以下内容:

void anything();

/* INCLUDED FROM a.h */
class Fooness{
public: 
Fooness(){
    anything();
    };
};

inline void anything() {
    ....
}
于 2013-01-21T03:32:40.393 回答
1

确保“未声明的标识符”是关于anything()而不是ii我在operator<<...中看到的

于 2013-01-21T03:32:31.230 回答