有人可以解释为什么我收到语法错误:在构建过程中没有class Bar;
在foo.hpp
头文件中包含标识符“ Bar”吗?
在构建之前,我在Visual Studio 2019中没有收到任何错误,并且构建顺序似乎是bar
,然后foo
,然后main
,因此在执行这些#include
语句之后,似乎在构建过程中bar
头文件首先包含在头文件中foo
。
我在下面包含了概述基本问题的代码。
//Foo header file
#pragma once
#include "bar.hpp"
#include <iostream>
class Bar; //Commenting this line out results in no longer being able to build the project
class Foo {
public:
Foo();
void pickSomething(Bar& bar);
};
//Foo cpp file
#include "foo.hpp"
Foo::Foo() {
std::cout << "Made Foo" << std::endl;
}
void Foo::pickSomething(Bar& bar) {
bar.getSomething();
std::cout << "Picked something!" << std::endl;
}
//Bar header file
#pragma once
#include "foo.hpp"
#include <iostream>
class Foo;
class Bar {
public:
Bar(Foo& foo);
void getSomething();
};
//Bar cpp file
#include "bar.hpp"
Bar::Bar(Foo& foo) {
std::cout << "Made bar" << std::endl;
}
void Bar::getSomething() {
std::cout << "Gave something!" << std::endl;
}
//main file
#include "foo.hpp"
#include "bar.hpp"
int main() {
Foo foo;
Bar bar(foo);
foo.pickSomething(bar);
return 0;
}
概要:
foo.hpp
包括bar.hpp
和bar.hpp
包括foo.hpp
。这是一个循环依赖性。#pragma once
请确保不再加载相同的标头(如果已加载)。
仅编译bar.cpp
失败(foo.cpp
并且main.cpp
将成功编译)
让我们在编译时跟随预处理器bar.cpp
。事情按以下顺序发生。
bar.cpp
包括 bar.hpp
bar.hpp
包括foo.hpp
。(注意以下两点)
bar.hpp
并且将避免在当前循环中再次输入它。Bar
(class的声明Bar
)仍未像foo.hpp
之前那样加载foo.hpp
尝试包括 bar.hpp
bar.hpp
,因此将被忽略!Foo
类声明使用名为的符号Bar
。但这是之前没有声明的!未知符号Bar
可能代表了很多东西(一个类,一个宏等)。因此,编译器(正确地)失败了,因为它不知道如何处理它。
解决方案是前向声明。在那里,您可以保证编译器该符号Bar
表示一个类。只要您没有在编译器需要了解类布局的地方做任何事情(例如,定义类型的成员函数Bar
,访问类的成员Bar
等),编译就会成功。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句