У меня есть такая структура:
struct OBJ {
int x;
const int y;
OBJ& operator=(OBJ &&oth)
{
y = oth.y; // this is disallowed
return *this;
}
}
И пример кода
void func() {
static OBJ obj;
OBJ other; // random values
if(conditon)
obj = std::move(other); //move
}
Я понимаю, что obj
является неконстантным OBJ с константным членом y
. Я не могу изменить только у, но я должен быть в состоянии изменить весь объект (вызов деструктора и конструктора). Возможно ли это или единственное правильное решение - удалить мой const
до y
и не забыть случайно изменить его?
Мне нужно сохранить мой static obj
между вызовами func
, но если условие истинно, я хочу переместить другой объект вместо этого статического объекта.
3 ответа
Я бы предложил перейти к std::unique_ptr
:
void func() {
static std::unique_ptr<OBJ> obj = std::make_unique<OBJ>();
std::unique_ptr<OBJ> other = std::make_unique<OBJ>(); // random values
if(condition)
obj = std::move(other); //move
}
Это должен быть ваш выбор во многих случаях, когда необходимо переместить что-то, что не может быть перемещено, чтобы удерживать неизвестный полиморфный тип, или любой другой случай, когда вы не можете иметь дело с реальным типом.
Как насчет написания оператора присваивания перемещения следующим образом:
OBJ& operator=(OBJ&& other) {
this->~OBJ();
new(this) OBJ(other.x, other.y);
return *this;
}
Вам также понадобится конструктор:
OBJ(const int x, const int y)
: x(x), y(y)
{
}
Вы делаете конструкторы неправильно. Конструкторы должны инициализировать , а не назначать:
OBJ(OBJ &&oth) : y(oth.y) {}
// ^^^^^^^^^^
Кроме того, конструкторы не могут return *this
, так как они не имеют возвращаемого типа.
Оператор присваивания для вашего класса не имеет смысла, так как класс имеет неназначаемые члены (а именно, константы). (Конечно, вы можете написать собственное назначение, которое не изменяет член const, но тогда у вас будет действительно странный класс, который ведет себя крайне удивительно.)
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .