3

私は に非常に慣れてC++いませんが、バックグラウンドを持っているので、ほとんどの概念Javaを理解しています。OOP入門ガイドを読んでいると、次の例に出くわしました。

[Foo.H] 
class A
{
    public:
       A(int something);
};

class B : public A
{
    public:
       B(int something);
};

[Foo.C] 
#include "Foo.H"

A::A(int something)
{
    printf("Something = %d\n", something);
}

B::B(int something) : A(something)
{
}

A(something)のイニシャライザ リストに渡すことで、Java のキーワードにB::B(int something)似ていると仮定するのは正しいですか? 別名、のコードを実行しますか? また、なぜイニタライザ リストからではなく呼び出すだけなのですか?superA::A(int something)A(something)A::A(something)

基本的に私は尋ねています:上記はこれと同等です:

B::B(int something)
{
    A::A(something)
}

私が混乱している理由を拡大させてください。

私が使用する場合:

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

そして、経由でコードを呼び出します

B::B(7);

これは印刷されますx = 5か、それともsomething = 7最初に印刷されますか? そして、なぜこの順序で実行されるのでしょうか?

この単純な例でさえ、継承が起こっていることを把握して視覚化するのを難しくしている構文について、私は少し混乱しています。

4

3 に答える 3

2

はい、A(something)その値を のように渡しますsuperA::A言語は基本クラス名を子クラスに自動的に挿入するため、使用する必要はありません。

ただし、同等ではありません

B::B(int something)
{
    A::A(something)
}

それは法的なコードではないからです。初期化子リストで呼び出す親コンストラクターのみを選択できます。

印刷についての質問ですが・・・試してみましたか?親something=が最初に出力され、続いてx=.

于 2013-07-24T16:48:51.780 に答える
1
A::A(int something)
{
    printf("Something = %d\n", something);
}

これは B のコンストラクターです。コンストラクターが最初に行うことは、その基本クラスを (コンストラクターの順序ではなく、クラスで宣言された順序で) 構築し、次に (クラスで宣言された順序で) メンバー オブジェクトを構築することです。 、コンストラクターの順序ではありません)、次に本体 ( のコード{}) を実行します。これを行う理由は、 aB オブジェクトであるためです。したがって、オブジェクトになり始める前にA完全でなければなりません。また、メンバー関数のコードを実行する前に、すべてのメンバーを完全に構築する必要があります。そうしないと、問題が発生する可能性があります。したがって、コンストラクター本体を開始する前に、基本クラスとメンバーの両方を構築する必要があります。AB

基本クラスまたはメンバーの初期化方法を変更したい場合 (たとえば、デフォルトの構築ではなく整数を渡すため)、それを初期化子リストに入れることができます。

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

のコンストラクターの名前を修飾する必要はありませんA。既にオブジェクト のコンテキストにあり、B既にBについて知っているからAです。

B::B(int something)
{
    A::A(something)
}

で本体を実行する前にオブジェクトをB作成するため、このコードは無効です。は既に構築されているため、本体で呼び出しても意味がなく、コンパイラがこれを診断します。A{}AA::A

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

前述のように、B を構築するときは、最初に基底クラスを構築し、次にメンバーを構築し、次に本体を実行します。したがって、あなたは見るでしょう

something = 7
x = 5
于 2013-07-24T17:03:39.230 に答える
1

いいえ、それらは同等ではありません

サブクラスのコンストラクターは、初期化子リストで明示的に指定しない限り、親のデフォルトのコンストラクターを呼び出します。

B::B( int something ) {}A::A()暗黙的に呼び出さAれ、デフォルトのコンストラクターがない場合はコンパイルされません。

B::B(int something)
{
    A::A(something)
}

これが何をするかというとA::A()、初期化子リストで暗黙的に呼び出し、次にA::A(something)を呼び出そうとするというAことです。

したがって、別の親コンストラクターを呼び出したい場合は、それを行う唯一の方法は、初期化子リストにあります。

B::B(int something) : A(something) {}
于 2013-07-24T16:52:13.467 に答える