-1

それは単純化されたコードです!私はC++ファイル(実装の場合)とヘッダーファイル(クラス定義の場合)を持っています!

main.hを含むFoo.cppというファイルがあります。そして、funcs Foo.cppを使用し、 main.hも含むファイルBar.cppがあります。構造体を使用して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()ます。

*編集済み*ヘッダーで機能する ことは知ってい#includeますが、「擬似コード」と書きました。readlプロジェクトでヘッダーファイルとcppファイルを使用し、ヘッダーのみをインクルード#pragma onceしてヘッダーに含めています。この質問では、コードを単純化するだけです。答える前にすべての質問を読んでください!

* EDITED2 * 今すぐコンパイルしようとしました。できます。変。

ありがとう。

4

3 に答える 3

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
}

私は十分に明確だったと思います。

于 2011-07-05T12:58:20.767 に答える
4

問題

ソースファイルを作成したり、ファイルを相互にソースしたりし#pragma onceないでください。#include

あなたの場合の問題(おそらく、しかしあなたのテストケースは正確ではありません):あなた#include "Foo.cpp"、しかしその瞬間、コンパイラは#pragma onceコンパイルするずっと前にすでにトリガーされていFoo.cppます。

簡単に言うと、ソースファイルとヘッダーファイルを混同しているため、コンパイラが混乱しています。

正規の手口

  • 各クラスのヘッダー/ソースペア

    • ヘッダーには通常、宣言のみが含まれます。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();
}
于 2011-07-05T12:59:39.240 に答える
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 ファイルであるということです。

于 2011-07-05T18:43:47.183 に答える