次の質問があります。これらのうちどれが従うべきであり、その理由はどれですか?
string strMyString = "SampleString";
また
string strMyString("SampleString");
前もって感謝します。
次の質問があります。これらのうちどれが従うべきであり、その理由はどれですか?
string strMyString = "SampleString";
また
string strMyString("SampleString");
前もって感謝します。
ここで答えた
ここでこの回答に入れたことの1つは、どちらも代入演算子を使用していないことです。
ただし、文字列固有のものの簡単な説明。std::string
を受け入れる 1 つの引数を取るコンストラクターがありますchar const*
。
// simplified to a normal class declaration. std::string actually
// is a template instantiation.
class string {
public:
string(char const* str) {
// copy over...
}
};
これで、文字へのポインターを取るコンストラクターがあることがわかります。文字列リテラルを受け入れることができるようにします。その場合、次のケースは明らかだと思います。
string s("hello");
コンストラクターを直接呼び出して初期化しますs
。これを直接初期化と呼びます。
変数を初期化するもう 1 つの方法は、コピー初期化と呼ばれます。標準では、イニシャライザが初期化しているオブジェクトの型を持たないコピー初期化の場合、イニシャライザは適切な型に変換されます。
// uses copy initialization
string s = "hello";
まずは種類を紹介
s
タイプは std::string です"hello"
この場合もポインタのように扱われる配列です。したがって、 とみなしますchar const*
。コンパイラは、変換を行う 2 つの方法を探します。
std::string
ますか?これらの方法の 1 つによって一時的なオブジェクトが作成され、それがのコピー コンストラクターを使用しstd::string
てオブジェクトを初期化するために使用されます。そして、初期化子を受け入れる変換コンストラクターがあることがわかります。だからそれを使う。結局、それは事実上s
std::string
std::string
std::string s(std::string("hello"));
すべてをトリガーした例で使用されているフォームに注意してください
std::string s = "hello";
暗黙的な変換を定義します。型の初期化規則が気になる場合は、コンストラクターを型に対して明示的にマークすることができます。これにより、対応するコンストラクターを変換コンストラクターとして使用char const*
できなくなります。
class string {
public:
explicit string(char const* str) {
// copy over...
}
};
copy initialization
そのため、 aと aを使用して初期化することは、char const*
現在 (および他のさまざまな場所で) 禁止されています!
これは、コンパイラがさまざまな場所で一時変数の省略をサポートしていない場合です。コンパイラは、コピー コンストラクターがこのコンテキストでコピーすると想定することができ、一時文字列の余分なコピーを削除し、代わりに一時 std::string を初期化されたオブジェクトに直接構築できます。ただし、特にコピー コンストラクターはアクセス可能でなければなりません。したがって、これを行うとコピーの初期化は無効になります
class string {
public:
explicit string(char const* str) {
// copy over...
}
private: // ugg can't call it. it's private!
string(string const&);
};
実際には、直接初期化の場合のみが有効です。
唯一の本当の違いは、最初のものは技術的にコピーコンストラクターの使用を必要とすることですが、コンパイラーはそれを削除して、両方の場合で効率が同じになるようにすることができます。
ただし、最初の方法では、実際に使用されていない場合でも、コピーコンストラクターにアクセスできる(つまり、プライベートではない)必要があります。