gpt4 book ai didi

c++ - 为什么我在编译期间收到语法错误?

转载 作者:行者123 更新时间:2023-11-30 04:42:35 28 4
gpt4 key购买 nike

有人能解释一下为什么我收到语法错误:在构建过程中没有在 foo.hpp 头文件中包含 class Bar; 标识符“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.hppbar.hpp 包含 foo.hpp。这是一个循环依赖。
  • #pragma once 确保不再加载相同的 header (如果已加载)。

  • 只有bar.cpp编译失败(foo.cppmain.cpp会编译成功)

让我们在编译bar.cpp 时跟随预处理器。事情按以下顺序发生。

  1. bar.cpp 包括 bar.hpp
  2. bar.hpp 包括 foo.hpp。 (注意以下两点)
    • 预处理器记住它输入了 bar.hpp 并将避免在当前循环中再次输入它。
    • 符号 Bar(类 Bar 的声明)仍未加载,因为在此之前包含 foo.hpp
  3. foo.hpp 尝试包含 bar.hpp
    • 预处理器知道它已经输入了 bar.hpp,因此忽略它!
    • 但是,Foo 类声明使用了一个名为Bar 的符号。但这之前没有声明过!

未知符号 Bar 可能代表很多东西(类、宏等)。所以编译器(理所当然地)失败了,因为它不知道如何处理它。

解决方案是前向声明。在那里,您向编译器保证符号 Bar 代表一个类。只要您没有在编译器需要了解类布局的地方做任何事情(例如,定义 Bar 类型的成员函数,访问 Bar 的成员等... ) 编译成功。

关于c++ - 为什么我在编译期间收到语法错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58677585/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com