Как написать конструктор перемещения и оператор присваивания для класса, который имеет частный объект в качестве свойства?

Сегодня я изучил конструкторы перемещения. Я прочитал этот ответ и попытался применить в нем пример конструктора перемещения к моему коду.

class UnicodeString
{
    public:
        enum  ENDIANNESS_TYPE {LITTLE_ENDIAN = 0, BIG_ENDIAN = 1} ENDIANNESS;
        bool  REPLACE_NON_ASCII_CHARACTERS;
        char  REPLACE_NON_ASCII_CHARACTERS_WITH;
        float VECTOR_RESERVE_COEFFICIENT;

        UnicodeString(UnicodeString && Other);

        // ...

        UnicodeString & operator=(UnicodeString Other);

        // ...

    private:
        std::vector<UnicodeChar> UString;

        // ...
}

UnicodeString::UnicodeString(UnicodeString && Other)
{
    this->REPLACE_NON_ASCII_CHARACTERS      = Other.REPLACE_NON_ASCII_CHARACTERS;
    this->REPLACE_NON_ASCII_CHARACTERS_WITH = Other.REPLACE_NON_ASCII_CHARACTERS_WITH;
    this->VECTOR_RESERVE_COEFFICIENT        = Other.VECTOR_RESERVE_COEFFICIENT;
    this->ENDIANNESS                        = Other.ENDIANNESS;
    this->UString = ?????
}

UnicodeString & UnicodeString::operator=(UnicodeString Other)
{
    std::swap(?????, ?????);
    return *this;
}

Однако, в отличие от этого примера, мой класс UnicodeString содержит не просто простой массив C. Он содержит объект std::vector<>, элементы которого являются экземплярами другого класса, который я написал.

Прежде всего, в конструкторе перемещения, как мне украсть вектор UString другого объекта, переданного R-Value?

Во-вторых, в операторе присваивания, как мне эффективно поменять местами ссылки UStrings основного объекта UnicodeString и переданного R-Value? Обратите внимание, что UString является частным свойством, поэтому к нему нельзя получить прямой доступ из другого объекта.


person hkBattousai    schedule 09.05.2013    source источник
comment
UnicodeString должны иметь возможность видеть друг друга UString, независимо от того, private они или нет. Спецификатор доступа применяется к другим клиентам.   -  person Benjamin Bannier    schedule 09.05.2013


Ответы (2)


Прежде всего, в конструкторе перемещения, как мне украсть вектор UString другого объекта, переданного R-Value?

Просто move() std::vector можно перемещать (operator=(vector&&)):

this->UString = std::move(Other.UString);

Во-вторых, в операторе присваивания, как мне эффективно поменять местами ссылки UString основного объекта UnicodeString и переданного R-Value? Обратите внимание, что UString является частным свойством, поэтому к нему нельзя получить прямой доступ из другого объекта.

Обратите внимание, что private относится к class, а не к экземпляру class. Это означает, что другие экземпляры одного и того же class могут получить доступ к private членам другого экземпляра. Итак, просто используйте std::move(Other.UString), как и раньше.

person hmjd    schedule 09.05.2013

Правильный способ сделать это (при условии, что вы используете Visual Studio и, следовательно, ваш компилятор не сделает это за вас) выглядит так, со списком инициализации:

Unicode::UnicodeString(UnicodeString && other)
  : this->REPLACE_NON_ASCII_CHARACTERS(other.REPLACE_NON_ASCII_CHARACTERS)
  , this->REPLACE_NON_ASCII_CHARACTERS_WITH(other.REPLACE_NON_ASCII_CHARACTERS_WITH)
  , this->VECTOR_RESERVE_COEFFICIENT(other.VECTOR_RESERVE_COEFFICIENT)
  , this->ENDIANNESS(other.ENDIANNESS)
  , this->UString(std::move(other.UString))
{
}

Обратите внимание, что UString является частным свойством, поэтому к нему нельзя получить прямой доступ из другого объекта.

Говорит кто? Частный означает, что код вне объекта не может получить к нему доступ. Но один экземпляр объекта наверняка может получить доступ к приватным данным другого экземпляра объекта.

person Nicol Bolas    schedule 09.05.2013