Я научился Переместить Конструкторы сегодня. Я читаю этот ответ, и я попытался применить пример конструктора перемещения в моем коде.
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-значением?
Во-вторых, в операторе присваивания, как эффективно поменять местами ссылки на UString
с основной UnicodeString
объект и тот, переданный R-Value? Заметить, что .UString
является частной собственностью, поэтому к ней нельзя напрямую получить доступ из другого объекта
Прежде всего, в конструкторе перемещения, как я могу украсть вектор UString другого объекта, переданного R-Value?
Просто move()
std::vector
как подвижно (operator=(vector&&)
):
this->UString = std::move(Other.UString);
Во-вторых, как в операторе присваивания эффективно обмениваться ссылками на строки UStrings основного объекта UnicodeString и те, которые передаются R-Value? Обратите внимание, что UString является частной собственностью, поэтому к ней нельзя напрямую получить доступ из другого объекта.
Обратите внимание, что private
относится к class
, а не к примеру class
, Имея в виду другие случаи того же class
может получить доступ к private
члены другой инстанции. Так что просто используйте std::move(Other.UString)
как прежде.
Правильный способ сделать это (при условии, что вы используете 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 является частной собственностью, поэтому к ней нельзя напрямую получить доступ из другого объекта.
Говорит кто? Приватный означает, что код вне объекта не может получить к нему доступ. Но один экземпляр объекта, безусловно, Можно получить доступ к частному экземпляру другого объекта.