0

コンストラクターの変換はどのように機能しますか?

#include <iostream>
using namespace::std;

class One {
public:
    One() { cout<<"One"<<endl;}
};

class Two {
public:
    Two(const One&) {cout<<"Two(const One&)"<<endl;}
};

void f(Two) {cout<<"f(Two)"<<endl;}

int main() {
    One one;
    f(one); 
}

出力を生成します

One
Two(const One&)
f(Two)
4

4 に答える 4

3

単一の引数で呼び出すことができるコンストラクターは、 と見なされますimplicit conversion constructor。これには、引数が 1 つの単純なケースと、既定の引数の使用が含まれます。

この変換は、X が必要で Y が提供された任意のコンテキストで考慮され、Y にはそのような暗黙的な変換の可能性があります。他の多くの組み込み変換も組み合わせて機能することに注意してください (const-ness の調整、整数と fp の昇格、変換など)。ミックス。

場合によっては非常に驚くべきことかもしれないので、一般的なアドバイスはそのような ctors を作成することですexplicit。そのキーワードは変換を可能にしますが、暗黙的にではありません: 強制するには T() 構文を使用する必要があります。

例としてstd::vector、初期サイズを設定する size_t を取る ctor があるとします。これは明示的です -- そうしないと、foo(vector<double> const& )関数が誤って foo(42) で呼び出される可能性があります。

于 2013-06-20T09:33:44.037 に答える
0

コンストラクターが意味することは、いつでも - 暗黙的に - から値Two(const One&) {cout<<"Two(const One&)"<<endl;}を構築できるということです。呼び出すと、パラメーターが必要になるため、コンパイラーは 2 と 2 を組み合わせて、「から一時的なものを作成し、呼び出しを完了します」と言います...誰もが幸せになります。万歳!TwoOnef(one)TwoOneTwoOnef()

于 2013-06-20T09:26:14.327 に答える
0

コンパイラはTwoスタック上にインスタンスのコピーを作成する必要があります。クラス(またはその他の)f()オブジェクトである引数を指定して呼び出すと、コンパイラはクラスの定義を調べ、(またはその他の)オブジェクト(または参照)を引数として取るコンストラクターを見つけようとします。そのようなコンストラクターが見つかると、それを使用してオブジェクトを構築します。コンパイラがあなたの干渉なしにそれを行うため、暗黙的と呼ばれます。OneTwoOne

class Foo {
public:
    Foo(int number) {cout<<"Foo(int number)"<<endl;}
};

void f(Foo) {cout<<"f(Foo)"<<endl;}

int main() {
    f(24); 
} ///:~

出力は次のようになります: Foo(int number) f(Foo)

于 2013-06-20T09:22:33.733 に答える
0

正しい結果です。constructorではないので-explicit暗黙の変換が機能します (ここでOneは暗黙的に に変換されTwoます)。

oneが作成され、渡されると にf変換されTwoます。

于 2013-06-20T09:16:51.343 に答える