次のようなクラスのオブジェクトを宣言するとmyclass
:
myclass ob1(5);
これは、パラメーターを受け入れる2 番目のコンストラクターで作成したことを意味します。int
つまり、文字通り2 番目のコンストラクターを呼び出しました。ちなみに、オブジェクトはスタック上に作成されます。
次のようなクラスのオブジェクトを宣言するとmyclass
:
myclass ob1;
これは、パラメーターのない最初のコンストラクターで作成したことを意味します。パラメーターなしのコンストラクターの正しい用語は、既定のコンストラクターです。つまり、文字通りデフォルト(最初のコンストラクター) のコンストラクターを呼び出しました。ところで、オブジェクトもスタック上に作成されます (前のケースのように)。
オブジェクトがスタック上に作成されると、オブジェクトがスコープ外になると自動的に破棄されます。スコープの概念は、関数/メソッド/ブロックを含むコードのブロックに適用されます。中かっこのペアでブロックを簡単に区別できます{}
。例えば:
void function() {
myclass ob1;
} // <--- think of ob1 being destructed at this point
関数の実行が終了すると、オブジェクトob1
はスコープ外になり、それに応じてデストラクタob1
が自動的に呼び出されます。もう一つの例:
void function() {
while(true) {
myclass ob1;
} // <--- think of ob1 being destructed at this point
// ob1 does not exist here!
}
無限ループと、ob1
反復ごとにその内部に作成されたオブジェクトに注目してください。中括弧は、各反復を構成する複数のステートメントを組み合わせることができるブロックを定義することが明確にわかります (現在、ステートメントは 1 つしかありません)。したがって、オブジェクトob1
は各反復の最後に自動的に破棄されます。
スコープの概念は、クラス メンバーにも適用されます。たとえば、 classがあり、そのメンバー ( ) として次のようにwrapper
宣言するとします。myclass
m1
class wrapper {
public:
myclass m1;
};
wrapper
次に、前の例の 1 つを使用して、スタック上にオブジェクトを作成します。
void function() {
wrapper w;
} // <--- destructor of w called first, destructor of w.m1 is called after
最初に のデフォルト コンストラクターの実行w
が開始され、その間にが作成されます (この場合、呼び出したいコンストラクターのw.m1
コンストラクターを指定しなかったため、デフォルト コンストラクターを使用します)。その後、 のコンストラクターが実行を終了し、正式に作成されたと見なすことができます。の実行が続きます。w
w.m1
w
w
function
function
実行が終了するw
と、範囲外になり、覚えているように、そのデストラクタが自動的に呼び出されます。w
のデストラクタが実行を終了するとすぐに、のデストラクタw.m1
も自動的に呼び出されます。オブジェクトw
が生きている間は独自の内部スコープを持ち、死ぬとすぐに、そのすべてのメンバーがスコープから外れて死ぬ必要があると考えることができます。