编译器错误-定义问题.C++

compiler errors - Defining trouble. C++

本文关键字:问题 C++ 定义 错误 编译器      更新时间:2023-10-16

这是一个简化的代码!我有C++文件(其中是实现(和头文件(其中为类定义(

我有一个文件:Foo.cpp,其中包含main.h。我有文件Bar.cpp它使用函数Foo.cpp,还包括main.hain.h中定义的结构?我试着这样解决:

**IN MAIN.H**
#pragma once
class Foo;
struct FoobarPackage {
    FoobarPackage(Foo *fooObj) {
        soso = fooObj;
    }
    Foo *soso;
};
* * *
**IN FOO.CPP**
#pragma once
#include "main.h"
class Foo {
    void doSomething(bool ololo) {
    if (ololo) //do something else
    }
};
* * *
**IN BAR.CPP**
#pragma once
#include "main.h"
#include "Foo.cpp"
class Bar {
    bool killAllHumans(FoobarPackage planet) {
        planet.soso->doSomething(true);
        return true;
    }
};
* * *

但它导致:

Bar.cpp:8: error: invalid use of incomplete type "struct(WTF??!!! —  author's comment) Foo"
main.h:3: error: forward declaration of "struct(why struct?) Foo"

我的代码出了什么问题?而且它不是真正的代码。我简化了我的真实项目,削减了所有不需要的东西。Foo.cpp和Bar.cpp当然在定义Foo和Bar类的地方有它们的头,而在.cpp文件中,这只是它们的实现。此外,killAllHumans()main()所在的main.cpp调用。

*编辑*我知道#include可以处理头,但我写过它是"伪代码"。我在readl项目中使用头文件和cpp文件,并且在头中只包含头和#pragma once。在这个问题中,我只是简化了我的代码!请在回答之前阅读所有问题!

*编辑2*现在尝试编译它。它有效。奇怪的

谢谢。

您不应该在C++中包含.cpp("代码文件"(。

始终在Header(.h(文件中进行定义。您必须创建foo.h和bar.h文件,然后将它们包含在main.h 中

使用.cpp来定义功能,使用.h来定义函数原型,如下所示:

// foo.h
#pragma once
#include "main.h"
class Foo {
public:
    void doSomething(bool ololo);
};
// foo.cpp
#include "foo.h"
void Foo::doSomething(bool ololo)
{
    if (ololo) //do something else
}

我希望我已经足够清楚了。

问题

不应将#pragma once放在源文件中,也不应将#include源文件相互放入。

您的案例中的问题(可能是,但您的测试案例并不准确(:您#include "Foo.cpp",但此时编译器早在编译Foo.cpp时就已经触发了#pragma once

简单地说:编译器被混淆了,因为你混淆了源文件和头文件

典型操作方法

  • 每个类别的标题/源对

    • 标头通常只有声明,例如class Foo { void someMethod(); };

    • 源包括标头并定义类成员,例如void Foo::someMethod() {...}

  • 其他翻译单元("源文件"(可以愉快地#include报头

示例

foo.h

#ifndef FOO_H
#define FOO_H
#pragma once   // note: compiler extension, do as
               //       you prefer, advantage of #pragma 
               //       once is near to nothing on today's
               //       compilers, though
class Foo {
public:
    void someMethod();
};
#endif

foo.cpp

#include "foo.h"
void Foo::someMethod() {
    // do something
}

然后,你可以在其他翻译单元中使用它,比如:

main.cpp

#include "foo.h"
int main () {
    Foo foo;
    foo.doSomething();
}

适用于我:

$ cat main.h 
#pragma once
class Foo;
struct FoobarPackage {
    FoobarPackage(Foo *fooObj) {
        soso = fooObj;
    }
    Foo *soso;
};
$ cat Foo.cpp 
#pragma once
#include "main.h"
class Foo {
public:
    void doSomething(bool ololo) {
    if (ololo) ; //do something else
   }
};
$ cat bar.cpp
#pragma once
#include "main.h"
#include "Foo.cpp"
class Bar {
    bool killAllHumans(FoobarPackage planet) {
        planet.soso->doSomething(true);
        return true;
    }
};
$ g++ -c bar.cpp
bar.cpp:1:9: warning: #pragma once in main file
$ $ g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 
$

编辑:正如每个都指出的,这个程序仍然非常有缺陷。最重要的是,它#include是一个CPP文件,没有明显的原因。