3

例:

H

class MyClass {
    int x,y,z;
public:
    MyClass(int,int,int);
    void X();
    void Y();
    void Z();
};

CPP

class MyClass {
    int x,y,z;
public:
    MyClass(int x,int y,int z) {
        this->x=x;
        this->y=y;
        this->z=z;
    }
    void X() {
        printf("x = %d;\n",x);
    }
    void Y() {
        printf("y = %d;\n",y);
    }
    void Z() {
        printf("z = %d;\n",z);
    }
};

C# ライクにします。ヘッダーを含めず、CPP でクラスを再宣言しますが、メソッド本体を使用します。ファイルにヘッダーが含まれている場合、彼は CPP から extern フィールド\メソッドなどを取得します。

それは合法ですか?そこから問題を予測することはできません。がある?

4

3 に答える 3

11

これは、One Definition Rule の領域に該当します。特に、同じクラスの単一プログラムの複数の TU にわたる複数の定義に課せられる要件は次のとおりです。

[...] — D の各定義は、同じ一連のトークンで構成される [...]

(3.2 1 つの定義規則 [basic.def.odr] の 5 項)

したがって、最初のバージョンを「修正」してinline、2 番目のバージョンに一致するようにメンバー関数を宣言したとしても (メンバーの定義を提供すると暗黙的に宣言されますinline)、このルールに違反することになります: 関数本体は、に現れる追加のトークンです。一方ではなく、他方ではありません。

于 2012-10-11T14:54:21.237 に答える
5

これは、1つの定義ルールセクションの3.2/5では許可されていません。

クラスタイプの定義は複数存在する可能性があります(9節)...[関係のない他のタイプと条件]

...そして、定義が次の要件を満たしている場合。複数の翻訳単位で定義されたDという名前のそのようなエンティティが与えられた場合、

--Dの各定義は、同じトークンのシーケンスで構成されます。

これは、ヘッダーが他のリンクされた変換ユニットに含まれている場合、そのようなメカニズムを明確に禁止します。

C#を記述したい場合は、C#で記述してください。方言の代わりに慣用的なC++を書くと、将来のメンテナはそれを大いに評価するでしょう。

于 2012-10-11T14:51:58.000 に答える
-1

主な問題は循環参照です。 class のコードに、それ自体が class を使用する classAのインスタンスが含まれている場合、コンパイルは失敗します。BA

クラスを宣言 (.h) と定義 (.cpp) に分離すると、この問題が解決されます。

ただし、クラス定義をヘッダー ファイルに配置したい場合は、クラスをテンプレートにして、型解決を効果的に延期することで実行できます。しかし、これにはコンパイル時間の増加という代償が伴います!

于 2012-10-11T14:54:27.980 に答える