这是简化的代码!我有C ++文件(在哪里实现)和标题文件(哪些是定义)
我有一个文件: Foo.cpp ,其中包含 main.h 。我有 Bar.cpp 文件,它使用funcs Foo.cpp ,还包括 main.h 。它使用struct来访问Foo对象并调用它的函数。但结构在 main.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.cpp调用,其中main()
位于。
*的 EDITED *
我知道#include
适用于标题,但我写道它是“伪代码”。我在我的readl项目中使用头文件和cpp文件,只包含头文件,#pragma once
在我的标题中。在这个问题中,我只简化了我的代码!请在回答之前阅读所有问题!
*的 EDITED2 * 试图现在编译它。有用。奇怪。
感谢。
答案 0 :(得分:4)
您不应在C ++中包含.cpp(“代码文件”)。
始终在页眉(.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
}
我希望我足够清楚。
答案 1 :(得分:4)
您不应该在源文件中#pragma once
,并且不得#include
将文件相互导入。
您的情况下的问题(可能,但您的测试用例并不准确):您#include "Foo.cpp"
,但此时,编译器在编译{{{}}之前很久就已触发#pragma once
1}}。
简单来说:编译器因为您将源文件与头文件混合而感到困惑。
每个类的标头/源对
标题通常只有声明,例如Foo.cpp
源包括标题并定义类成员,例如class Foo { void someMethod(); };
其他翻译单元(“源文件”)可以很高兴void Foo::someMethod() {...}
标题
<强> foo.h中强>
#include
<强> Foo.cpp中强>
#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
然后,您可以在其他翻译单元中使用此功能:
<强>的main.cpp 强>
#include "foo.h"
void Foo::someMethod() {
// do something
}
答案 2 :(得分:1)
适合我:
$ 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文件,没有明显的原因。