Списки инициализаторов и перегрузка присваивания (оператор =) - PullRequest
1 голос
/ 21 февраля 2012

Распространяется ли перегрузка оператора присваивания в список инициализаторов?

Например, предположим, класс:

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.

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Полагаю, он будет использовать конструктор копирования, а не оператор присваивания.

2 голосов
/ 21 февраля 2012
MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

Обратите внимание, что здесь у вас есть две копии: одна для инициализации параметра myString, а другая для инициализации члена m_myString.Вы этого не хотите.В C ++ 03 вы берете параметр по константной ссылке:

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

А в C ++ 11 вы берете параметр по значению и затем вручную перемещаете его в член:

MyClass::MyClass(std::string myString)
 : m_myString(std::move(myString))
{
}
2 голосов
/ 21 февраля 2012

Я думаю, что вам не хватает разницы между 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

И списки инициализаторов выполняют только инициализацию (отсюда и название initializer list).

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...