2011-12-19 28 views
2

開発者によって明示的に宣言されたdestructorおよびを持たないクラスのケースを考えてください。この場合、クラスのdestructorimplicitly declaredになります。それで、クラスのオブジェクトが破壊される直前のときに、destructorimplicitly definedであることは本当ですか?暗黙的に定義されたクラスのデストラクタ

コンストラクタの動作も上記と同じですか?それはimplicitly definedクラスのオブジェクトが作成されるときだけですか?上記のコードで

EDIT

class A { 
    public: 

}; 
int main() { 

} 

、〜A()暗黙的に宣言されるであろう。私の質問は、それは本当のデストラクタの定義は、クラスのオブジェクトが

class A { 
     public: 

    }; 
    int main() { 
     A a; 
    } 

のようにインスタンス化されている場合にのみ、暗黙のうちに行われるか、暗黙的にオブジェクトのインスタンス化が行われていない場合でも、定義されていることかどうか?

+0

これはなぜ関連性があるのか​​を説明すると、より良い回答が得られるかもしれません。 –

+0

「暗黙に宣言された」と「暗黙的に定義された」の区別をしていますか?私は本当に質問を理解するために苦労しています... – NPE

+0

わかりやすくするためにいくつかのコードスニペットを追加しました。 –

答えて

5

はい、暗黙的に宣言されたデフォルトコンストラクタとデストラクタは、オブジェクトのインスタンスを作成または破棄するために暗黙的に定義されます。

12.1/6:標準(C++ 11)の言葉で、作成するODR-使用 (3.2)である場合、削除としてデフォルトと定義されていないデフォルトのコンストラクタが暗黙的に定義されていますそのクラス型のオブジェクト(1.8)または最初の宣言の後に明示的にデフォルトされているとき

12.4/5:odr-used(3.2)から のクラスタイプ(3.7)のオブジェクトを破棄したとき、またはそのクラスの後に明示的にデフォルト設定されているときに、デフォルトで削除されていないデストラクタが暗黙的に定義されます。最初の宣言。

だから彼らはしない、タイプAのオブジェクトを作成し、破壊し、あなたの2番目のコードスニペット、で定義されてではなく、最初にされています。

+0

パーフェクトアンサー。ありがとう –

0

一方で、あるオブジェクトが作成されたかどうかを判断することは不可能ですが、それ以外のプログラムでは破壊されます。*一方、観察可能な振る舞いが残っていれば問題はありません同じ。

ただし、defined when object created/destroyeddefined if neededの間に細い線があります。下の私の例では、Foo::Foo()を定義する必要があります。なぜなら、それが必要となる可能性があるからです。ただし、オブジェクトが作成されたときに定義されているかどうかと、オブジェクトが定義されているかどうかを尋ねます。


*:関数が定義されているかどうか

class Foo {}; 
int main(int argc, char *argv[]) { 
    if (argc>1) Foo(); // <- impossible to decide if ever constructed/destroyed 
} 

// On the other hand, compiler might be smart enough to observe that 
// Foo does not have any visible behaviour, remove Foo entirely, and in 
// effect spit out this: 
int main() {} 
+0

プログラムがオブジェクトを作成または破棄するためのコードを含む必要があるかどうかを判断することは、常に可能です(例では明らかです)。それは、暗黙のコンストラクタまたはデストラクタが定義されるかどうかを決定するものです。 –

+0

@Mike Seymour:もちろん、あなたは正しいですが、OPは基本的に '必要ならば定義されていますか? 'と尋ねるのではなく、'オブジェクトが作成されたときに定義されます '(私はより明確にするために投稿を更新しました)。 –

0

は、実行時に決定されるものではありませんので、オブジェクト[..]はおよそである場合にのみ、デストラクタは「は、定義することはできません破壊する "実行可能ファイルは静的であり、特定の実行に対しては作成されていないためです。あなたのデストラクタへの呼び出しが最終的な実行可能ファイルに存在しない場合

しかし、リンカかもしれないは完全に機能を削除しますに選びました。最後の点については


、この例で考えてみましょう。あなたは今までに何B::B()なしB::~B()が合成されていないので、これは実際にコンパイルおよびリンクしますBをインスタンス化したことがない場合は

class A { 
    A() {} 
    ~A() {} 
}; 
class B { 
    A a; // cannot access dtor nor ctor of A 
}; 

。しかし、Bのオブジェクトを作成しようとすると、コンパイラはいくつかのカラフルな名前を呼び出すでしょう。なぜなら、あなたはそれができないB::B()B::~B()を合成することが強制されたからです。

+0

デストラクタへの呼び出しが存在しない場合、コンパイラはデストラクタをまったく定義しません。なぜなら、それは標準のことであるからです。そしてあなたの例は運がうまくいくわけではありません。 'B'がインスタンス化されない限り、コンストラクタが定義されていないために動作します。 –

+0

@MikeSeymour:コンパイラはどのように知っていますか?呼び出しは他のコンパイル単位で行うことができますか? – bitmask

+0

インライン関数を扱うのと同じ方法です。コンストラクタ/デストラクタは、それを必要とするすべての翻訳単位で定義され、必要に応じて複製がリンカによってソートされます。 –

関連する問題