Мой объект - просто std::vector
. Когда я перемещаю его, компилятор просто перенаправляет указатель своего базового массива в массив вектора rvalue. Когда я копирую назначить его (а предыдущий вектор был длиннее), тогда его базовый массив будет перезаписан, но их адреса останутся прежними. К сожалению, в «некотором коде» хранятся указатели типа &a[2]
, и они могут не изменяться.
Тогда вам потребуется нечто иное, чем назначение копирования, поскольку назначение копирования также небезопасно.
Конечно, этот пример работает:
auto a = std::vector{1, 2};
auto const b = std::vector{3, 4};
auto pointer = a.data() + 1; // points to second element
a = b; // copy
std::cout << *pointer; // prints 4?
Это может работать, но не всегда!
Учтите это:
auto a = std::vector{1, 2};
auto const b = std::vector{3, 4, 5}; // three elements!
auto pointer = a.data() + 1; // points to second element
a = b; // copy. a's buffer is too small, must reallocate
std::cout << *pointer; // points in the old buffer, invalid.
Указатель на элементы вектора, который затем назначается, является небезопасным !
Что вы можете сделать тогда?
Определите свою собственную операцию:
struct Object {
// ... stuff
auto safe_assign(Object const& other) & -> void {
mem1 = other.mem1;
mem2 = other.mem2;
// let 'mem_vec' be your memeber vector
assert(mem_vec.size() == other.mem_vec.size());
// safe copy, will never reallocate.
std::copy(other.mem_vec.begin(), other.mem_vec.end(), mem_vec.begin());
}
};