C ++で参照によって一時オブジェクトを渡すときにコンストラクタを明示的に呼び出すことを避ける方法は?
-
06-07-2019 - |
質問
クラスがあるとしましょう:
class String
{
public:
String(char *str);
};
2つの関数:
void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);
次のようにDoSomethingByValを呼び出す場合:
DoSomethingByVal("My string");
コンパイラは、一時的なStringオブジェクトを作成し、char *コンストラクターを呼び出す必要があると判断します。
ただし、DoSomethingByRefを同じ方法で使用しようとすると、「パラメーターを「char *」から「String&」に変換できません」"エラー。
代わりに、明示的にインスタンスを作成する必要があります:
DoSomethingByRef(String("My string"));
これは欲求不満を招く可能性があります。
これを回避する方法はありますか?
解決
const参照で渡す必要があります:
For:
void DoSomethingByVal(String Str);
この状況では、コンパイラーはまず一時変数を作成します。次に、一時変数がパラメーターにコピー構築されます。
For:
void DoSomethingByRef(String const& Str);
この状況では、コンパイラは一時変数を作成します。ただし、一時変数は参照にバインドできません。const参照にのみバインドできるため、元の関数を呼び出すことはできません。 std :: stringオブジェクトコンストラクターは、const参照がコピーコンストラクターへのパラメーターであるため、最初のバージョンは、一時的コピーコンストラクターのconst参照パラメーターのみにバインドされるため、最初のバージョンが機能することに注意してください。
他のヒント
うーん、私はわからない
void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));
実際にコンパイルされます。右辺値は非constへの参照にバインドできません(非constへのrefは値を変更することを示しているため、一時的な値を変更することは意味がありません)。本当にやっていませんか:
String str("My string");
DoSomethingByRef(str);
DoSomethingByValで右辺値を取得する場合、パラメーターはconstへの参照である必要があります。
void DoSomethingByRef(const String &Str);
作成:
DoSomethingByRef(const String& str);
"マイストリング"文字列ではなく、C文字列、char *です。そのc-stringをStringオブジェクトに入れる必要があり、その後、参照によって新しいStringオブジェクトを渡すことができます。
もう1つのポイントは、char *を既に渡していることです...これは非常に軽量で、単なるポインターです。なぜ参照によって新しいオブジェクトを渡すことを心配するのですか?そのコンストラクタ内にヒープから新しいオブジェクトを割り当て、c-stringをその中にコピーするだけです。