2011-09-30 8 views
11

私は教科書で何かを読んだ後、少し混乱しています。コードについて:これはキャストか建設ですか?

void doSomeWork(const Widget& w) 
{ 
    //Fun stuff. 
} 

doSomeWork(Widget(15)); 

doSomeWork()const Widget&パラメータを取ります。教科書Effective C++ IIIは、doSomeWorkに渡す一時的なWidgetオブジェクトを作成すると述べています。

doSomeWork(static_cast<Widget>(15)); 

両方のバージョンがキャストされているため、最初のものは機能スタイルのCキャストのみです。私はWidget(15)が1つの整数パラメータをとっているウィジェットのコンストラクタを呼び出すと思っていたでしょう。

この場合、コンストラクタは実行されますか?

答えて

12

C++では、この種の式は、少なくとも構文的にはキャストの形のです。私。 C++機能キャスト構文Widget(15)を使用して、タイプWidgetの一時オブジェクトを作成します。つまり、あなたはそれがまだ機能キャスト表記の変化と考えられている(Widget(1, 2, 3)のように)多引数のコンストラクタを使用して、一時的に構築しても

(5.2.3を参照)

、あなたの「ですこれは鋳造と建設の間の相互排他性を意味するので、この鋳造または建設の質問は間違って述べられている。彼らは相互に排他的ではありません。実際、すべての型変換(明示的なキャストまたはもっと暗黙的なものである)は、ターゲット・タイプの新しい一時オブジェクト(おそらく、いくつかの参照初期化を除く)の作成(「構築」)以外のものではありません。

ところで、機能的なキャスト表記法は主にC++の表記法です。 C言語には機能スタイルのキャストはありません。

1

あなたが言った:最初は明らかに

最初ははCでをコンパイルしていないのと同じ関数スタイルのCキャストである

を、それがCスタイルではありません。 Cスタイルは(Widget)15のように見えます。ここでは、Widget::Widget(int)を使用して一時オブジェクトが作成されます。

したがって、Cスタイルのキャストではありません。

+1

@ Constantinius:正確に何が間違っていますか? – AnT

+0

私はあなたの答えを編集しました。 –

-1

Yeeeah。あなたはWidgetコンパイラにintをキャストD

Widget::Widget(int);を探し、そこにそれを置く:それはコンパイラによってバック置き換えられますので、あなたは

static_cast<Widget>(15) 

Widget(15) 

を置き換えることができます。

5

短い:はい。

ロング:

あなたは常に

W(1) 
W(2) 
W(3) 
+0

最初のものはキャストされていません。あなたは何を見せようとしましたか? – MSalters

+2

@MSalters:ほとんどの型では、キャストは(一時的な)オブジェクトを作成することと変わりありません。 – PlasmaHH

+1

@MSalters:私は彼が違いを見せようとしていたと思う –

3

を出力している:例えば

#include <iostream> 

struct W 
{ 
    W(int i) 
    { 
     std::cout << "W(" << i << ")\n"; 
    } 
}; 

int main(int argc, const char *argv[]) 
{ 
    W w(1); 
    W(2); 
    static_cast<W>(3); 
} 

を行うことによって、それらのものを自分でテストすることができますはい、それは両方です:)。キャストは構文構造(つまり、あなたが入力するもの)です。この場合、コンストラクタはキャストの結果として呼び出されます。コンストラクタのような多くは

Widget w(15); 
3

両方Widget(15)static_cast<Widget>(15)を入力した結果として呼び出されるご希望の場合は、キャスト、または変換 演算子です。両方とも15Widgetに変換することによって、指定された 型の新しいオブジェクトを作成します。 15には 変換演算子がありません。この変換を行う唯一の方法は、 (スタック上に)必要なメモリを割り当てて 適切なコンストラクタを呼び出すことです。これは、我々は通常のコンストラクタを持つよう doubleないと思う(しかし、その結果doubleint型を持つ15は異なる新しい オブジェクト、である)ことを除いて、本当に変わらないdouble(15)static_cast<double>(15)ということです。

0

はい、もちろんです。 CONVERSION CONSTRUCTORとみなされる単一のパラメーターを取るコンストラクターがあります。あなたのコンストラクタはすでにintというパラメータを1つ取っているので、コンパイラはこのコンストラクタを(暗黙的に)引数15(これはint)と一致するように "暗黙的に"呼び出すことができます。

このようなエラーを防ぐには簡単なトリックがあります。コンストラクタの前にキーワードexplicitを使用してください。

詳細については、thisを確認してください。

関連する問題