Помощник для перемещения и копирования
В настоящее время некоторые классы в нашей кодовой базе используют оператор присваивания в конструкторе (ctor), чтобы избежать дублирования кода, как видно из проблемы №1517. Однако в проблеме №1686 отмечается, что самоприсваивание не должно происходить в ctor. Поэтому необходимо принять альтернативный подход, чтобы заменить текущую реализацию.
Один из методов включает размещение общего логического кода в отдельной функции, которая далее называется copy_and_move_impl
. Эта функция затем вызывается в ctor и операциях присваивания с использованием параметров шаблона для указания метода инициализации члена.
Когда класс выполняет задачи, которые сильно согласуются во время построения (ctor) и присваивания, разработчики часто извлекают повторяющиеся части в отдельную функцию copy_and_move_impl
. Однако неизбежно существуют небольшие различия между перемещением, копированием и ctor, присваиванием (например, во время ctor определённые переменные должны быть инициализированы, чтобы избежать влияния мусорных значений на последующее поведение и т. д.). В этих случаях можно использовать MoveAndCopyHelper
, чтобы упростить код.
MoveAndCopyOperations
— класс перечисления, включающий:
CopyConstructor
MoveConstructor
CopyAssignment
MoveAssignment
Цель MoveAndCopyHelper
:
CopyConstructor
) при вызове copy_and_move_impl
;copy_and_move_impl
;MoveAndCopyOperations
и принудительно использовать ctor или присваивание, удовлетворяя потребности пользователей в особых обстоятельствах.MoveAndCopyOperations
, чтобы описать ожидаемое поведение переменных-членов во время инициализации (например, используя копирование или перемещение). Передача этого перечисления в качестве параметра шаблона в copy_and_move_impl
гарантирует, что специальные конструкторы вызываются должным образом.transfer
, чтобы гарантировать, что процесс обмена переменными-членами соответствует MoveAndCopyOperations
.В настоящее время существует три функции: transfer
, create_new
и assign
. Описанные ниже сценарии кратко описывают подходящее использование каждой функции.
transfer
: это универсальная функция для передачи данных. Рекомендуется использовать её в случаях, когда вы не имеете дело с потенциально неинициализированной памятью.create_new
: в некоторых случаях, особенно во время операций конструктора, некоторые члены класса являются ленивой инициализацией. Для этих членов необходимо использовать конструктор копирования или перемещения, даже если они доступны через оператор присваивания.assign
: TBD.// header
#include "iox/move_and_copy_helper.hpp"
constexpr uint64_t CAPACITY {1024};
class Test
{
public:
Test();
Test(const Test&);
Test(Test&&);
Test& operator=(const Test&);
Test& operator=(Test&&);
uint64_t size();
private:
int m_data[CAPACITY];
uint64_t m_size{0};
}
// implementation
Test::Test(const Test& rhs)
{
copy_and_move_impl<MoveAndCopyOperations::CopyConstructor>(rhs);
}
Test::Test(Test&& rhs)
{
copy_and_move_impl<MoveAndCopyOperations::MoveConstructor>(rhs);
}
Test& Test::operator=(const Test& rhs)
{
// you may do self-assignment check in copy_and_move_impl
if (this != &rhs)
{
copy_and_move_impl<MoveAndCopyOperations::CopyAssignment>(rhs);
}
return *this;
}
Test& Test::operator=(Test&& rhs)
{
// you may do self-assignment check in copy_and_move_impl
if (this != &rhs)
{
copy_and_move_impl<MoveAndCopyOperations::MoveAssignment>(std::move(rhs));
}
return *this;
}
void Test::size()
{
return m_size;
}
template <MoveAndCopyOperations Opt, typename RhsType>
void Test::copy_and_move_impl(RhsType&& rhs)
{
// you can set alias to simplify code
``` ```
using Helper = MoveAndCopyHelper<Opt>;
// you can determine the current 'Opt' at compile time for compile-time branching decisions.
constexpr bool is_ctor = Helper::is_ctor;
constexpr bool is_move = Helper::is_move;
// self assignment check if needed
if constexpr (!is_ctor)
{
if (this == &rhs)
{
return;
}
}
// for ctor operation
if constexpr (is_ctor)
{
// reset something if needed
reset_something();
}
// transfer data example
for (uint64_t i = 0; i < rhs.size(); ++i)
{
// @Recommended method
Helper::transfer(m_data[i], Helper::move_or_copy(rhs.data[i]));
// @Alternative method
if constexpr (is_move)
{
Helper::transfer(m_dаta[i], std::move(rhs.dаta[i]));
}
else
{
Helper::transfer(m_data[i], rhs.data[i]);
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )