16

正しく質問したかどうかはわかりませんが、説明させてください。

まず、宣言と定義の違いを説明するこの記事を読みました: http ://www.cprogramming.com/declare_vs_define.html

次に、以前の調査から、ヘッダーファイルで変数と関数を定義することは悪い習慣であることがわかっています。これは、リンクフェーズ中に、同じ名前に対して複数の定義があり、エラーが発生する可能性があるためです。

しかし、なぜこれがクラスで起こらないのですか?別のSOの回答( 定義と宣言の違いは何ですか?)によると、以下はクラスDEFINITIONになります。

    class MyClass {
        private:
        public:
    };

上記の定義がヘッダーファイルにある場合。次に、おそらく、そのヘッダーを#includeする複数の.cppファイルを持つことができます。これは、クラスが複数の.oファイルでコンパイルされた後に複数回定義されていることを意味しますが、それほど問題は発生しないようです...

一方、ヘッダーファイルで定義されている関数の場合、明らかに問題が発生します...私が理解していることから...多分?

では、クラス定義の何がそんなに特別なのですか?

4

3 に答える 3

16

単一定義規則(3.2、[basic.def.odr])は、クラスと関数に異なる方法で適用されます。

1-変換ユニットには、変数、関数、クラスタイプ、列挙型、またはテンプレートの複数の定義を含めることはできません。

[...]

4-すべてのプログラムには、そのプログラムでodrで使用されるすべての非インライン関数または変数の定義が1つだけ含まれている必要があります[...]

したがって、(非インライン)関数はプログラム全体で最大1回定義できますが(呼び出された場合やodrで使用された場合は、1回だけ定義できます)、クラスは変換ユニット(ソースファイル)の数だけ定義できます。ただし、翻訳単位ごとに1回だけです。

これは、クラスが型であるため、変換ユニット間でデータを共有できるようにするために、クラスの定義が必要であるためです。元々、クラス(structCのs)には、リンカーのサポートを必要とするデータがありませんでした。C ++では仮想メンバー関数と仮想継承が導入されており、vtableのリンカーサポートが必要ですが、これは通常、vtableをメンバー関数(の定義)にアタッチすることで回避できます。

于 2013-02-01T20:27:24.230 に答える
1

クラス定義は、そのクラスのオブジェクトの一種の青写真にすぎません。structC時代から同じです。コード自体には、クラスや構造は実際には存在しません。

于 2013-02-01T20:27:30.020 に答える
0

クラス定義はクラスを定義しますが、そのクラスのオブジェクトは定義しません。クラス(または構造)を複数のファイルで定義しても問題ありません。これは、タイプを定義しているだけであり、そのタイプの変数ではないためです。定義があった場合、コンパイラーはコードを発行しません。
コンパイラは、このタイプのオブジェクト(つまり変数)を宣言した後にのみ、実際にコードを出力します。

class MyClass myvar;

また:

class MyOtherClass { 
    public: ...
    private: ...
} myvar;         // note the variable name, it instantiates a MyOtherClass

これは、 myvarの複数のインスタンスがインスタンス化される原因となるため、ヘッダーで実行したくないことです。

于 2013-02-01T20:34:10.393 に答える