1

代入演算子のオーバーロードは初期化子リストに伝播しますか?

たとえば、次のクラスがあるとします。

class MyClass {
    private:
        std::string m_myString; //std::string overloads operator =
    public:
        MyClass(std::string myString);
}

そしてコンストラクタ:

MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

初期化子リストは代入演算子のオーバーロードを解決しstd::stringますか? そうでない場合、回避策はありますか?

特にGCCの場合。

4

3 に答える 3

3

代入演算子ではなくコピーコンストラクターを使用すると思います。

于 2012-02-20T22:42:47.600 に答える
3

あなたが見逃しているのは と の違いだと思いassignmentますinitialization

基本型の簡単な例を見てみましょう。

int a = 10; // Initialization
a = 1; // Assignment

上記の例は単純で、理解するのは難しくありません。ただし、ユーザー定義型に入ると、オブジェクトが構築されるため、それほど単純ではありません。

たとえば、見てみましょうstd::string

std::string s1("String1"); // Initialization (constructs s1 using constructor)
std::string s2 = s1; // Initialization (constructs s2 using copy constructor)
std::string s3(s2); // Initialization (constructs s3 using copy constructor)

s1 = s2; // Assigns s2 to s1 using assignment operator

ここで重要なのはoperator=、さまざまなコンテキストでさまざまなことを意味することです。それはすべて左側にあるものに依存します。

  std::string s1 = "Hello"; // Lhs has std::string s1, so this is initialization
  s1 = "Bob"; // Lhs has only s1, so this is assignment

また、初期化子リストは初期化のみを行います (したがって、初期化子リストという名前が付けられています)。

MyClass::MyClass(std::string myString)
 : m_myString(myString) // Initialization
{
}

operator=コンストラクターの本体を呼び出すときは、初期化ではなく代入を行っていることに注意してください。

MyClass::MyClass(std::string myString)
{
    // m_myString(myString); <-- Error: trying to call like a function
    m_myString = myString; // Okay, but this is assignment not initialization
}
于 2012-02-20T23:32:40.657 に答える
2
MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

ここには2つのコピーがあることに注意してください。1つはパラメーターを初期化するためのmyStringもので、もう1つはメンバーを初期化するためのものですm_myString。あなたはそれを望まない。C ++ 03では、const参照によってパラメーターを取得します。

MyClass::MyClass(const std::string& myString)
 : m_myString(myString)
{
}

また、C ++ 11では、パラメーターを値で取得し、手動でメンバーに移動します。

MyClass::MyClass(std::string myString)
 : m_myString(std::move(myString))
{
}
于 2012-02-21T08:31:12.103 に答える