Я хотел бы определить класс для сортировки данных; когда маршаллинг закончен, я хотел бы move
отобразить данные изнутри, что, вероятно, приведет к аннулированию объекта маршаллинга.
Я считаю, что это возможно с помощью функции static
extractData
ниже:
class Marshaller
{
public:
static DataType extractData(Marshaller&& marshaller)
{
return std::move(marshaller.data);
}
private:
DataType data;
}
Это немного неудобно звонить, хотя:
Marshaller marshaller;
// ... do some marshalling...
DataType marshalled_data{Marshaller::extractData(std::move(marshaller))};
Могу ли я обернуть его с помощью функции-члена?
DataType Marshaller::toDataType()
{
return Marshaller::extractData(std::move(*this));
}
Это, конечно, можно было бы назвать с помощью:
DataType marshalled_data{marshaller.toDataType()};
... который, для меня, выглядит намного приятнее. Но эта вещь std::move(*this)
выглядит ужасно подозрительной. В контексте вызова toDataType()
, marshaller
нельзя использовать снова, но я не думаю, что компилятор может знать, что: тело функции может находиться вне блока компиляции вызывающего, поэтому нет ничего что marshaller
применил к нему move()
.
Это поведение undefined? Это прекрасно? Или где-то посередине? Есть ли лучший способ достичь той же цели, желательно без использования макроса или для явного вызова вызывающего? move
marshaller
?
РЕДАКТИРОВАТЬ: Как с g++, так и с Clang++, я обнаружил, что не только могу скомпилировать вышеупомянутый вариант использования, но я мог бы продолжать вносить изменения в базовые данные через маршаллер, извлеките измененные данные с помощью функции toDataType
. Я также обнаружил, что уже извлеченные данные в marshalled_data
продолжали изменяться на marshaller
, что указывает на то, что marshalled_data
разделяется между marshaller
и вызывающим контекстом, поэтому я подозреваю, что есть либо память -leak или undefined (от двойного удаления).
РЕДАКТИРОВАТЬ 2: Если я поставлю оператор печати в деструктор DataType
, он появится дважды, когда вызывающий абонент покинет область видимости. Если я включаю элемент данных в DataType
, у которого есть массив в нем, с соответствующими new[]
и delete[]
, я получаю a glibc
"двойное свободное или повреждение". Поэтому я не уверен, как это может быть безопасно, хотя в нескольких ответах сказано, что это технически разрешено. Полный ответ должен объяснить, что необходимо для правильного использования этой методики с нетривиальным классом DataType
.
РЕДАКТИРОВАТЬ 3: Это достаточно кроличьей дыры/червяков, которые я открыл еще один вопрос обратитесь к моим оставшимся проблемам.