Переместить конструктор/назначение для тривиального класса в связанный список

У меня есть простой класс с несколькими тривиальными членами и без каких-либо выделений. Я планирую добавить конструктор/назначение перемещения. Эти примитивы не будут более эффективными, чем обычные.

Вопрос первый: имеет ли смысл это делать, чтобы сделать мой класс более универсальным?

Существует внутренний список, связывающий объекты класса.

Вопрос второй: в каком состоянии мне следует оставить класс, из которого был перемещен: в списке или удален из списка? Планирую удалить его из списка.

Обновление: есть несколько комментариев по использованию ходов, генерируемых компилятором. Я не могу этого сделать, потому что есть внутренний список, о котором мне нужно позаботиться.

Итак, это либо ручные ходы, либо ничего. Фрагмент возможного кода ниже, многопоточности нет.

class A {
 public:
  static void Run() {
       A* cur = list_;
       while(cur) {
           cur->DoWork();
           cur = cur->next_;
       }
  }
   
  virtual ~A() { Remove(); }

  A() : next_(), data_(), in_list_() {
  }

  A(int data) : next_(), data_(data), in_list() {
    Insert();
  }

  A(A const& other) : next_(), data_(other.data_), in_list() {
    Insert();
  }

  A(A&& other) : next_(), data_(other.data_), in_list() {
    other.Remove();
    Insert();
  }

  A& operator=(A const& other) {
    if (this != &other) {
       data_ = other.data_;
       Insert();
    }
    return *this;
  }

  A& operator=(A&& other) {
    if (this != &other) {
      data_ = other.data_;
      other.Remove();
      Insert();
    }
    return *this;
  }

 private:
    void DoWork() { <do-something-important-with-data>; }

    void Insert() {
      if (_in_list) {
        return;
      }
      ...;
      in_list_ = true;
    }

    void Remove() {
      if (!_in_list) {
        return;
      }
      ...;
      in_list_ = false;
    };

  A* next_;
  int data_;
  bool in_list_;

  static A* list_;
};

Не добавляйте ничего из этого (конструктор копирования/перемещения/назначения), если в них нет необходимости. Не уверен, что вы подразумеваете под «более общим», но переопределение функций класса, которые компилятор сгенерирует для вас, не делая ничего полезного, для меня не имеет смысла.

Juliean 11.03.2024 22:04

пожалуйста, по одному вопросу на вопрос. И пожалуйста, покажите код, а не описывайте его.

463035818_is_not_an_ai 11.03.2024 22:05

Полагаю, вы имеете в виду «эффективный», а не «эффективный».

463035818_is_not_an_ai 11.03.2024 22:06

Второй вопрос звучит так, будто вы не поняли семантику хода.

molbdnilo 11.03.2024 22:09

обязательно прочитайте также о правиле нуля.

463035818_is_not_an_ai 11.03.2024 22:11

Перемещение тривиального типа ничем не отличается от его копирования. Создаваемых компилятором конструкторов копирования/перемещения по умолчанию и операторов копирования/перемещения будет достаточно.

Remy Lebeau 11.03.2024 22:11

другими словами, ход уже возвращается к копии. Нет смысла снова заставлять ваш класс реализовывать это резервное поведение.

463035818_is_not_an_ai 11.03.2024 22:14

Образовательный просмотр стоит потраченного времени: Презентация Говарда Хиннанта «Все, что вам нужно знать о семантике перемещения»

user4581301 11.03.2024 22:51

Вероятно, в этом примере достаточно, но общая рекомендация — отказаться от ... и предоставить пример кода, который люди смогут использовать в своих инструментах и ​​поиграть с ним. Удивительно, какие интересные вещи могут получить люди, если вы приведете полный пример. Но не переусердствуйте; придерживаться минимального воспроизводимого примера .

user4581301 11.03.2024 22:54

@user4581301 user4581301 Мой вопрос не в том, «как это сделать?». Мой вопрос: имеет ли это смысл?

uuu777 11.03.2024 23:19

Начнем с того, что ваш дизайн ошибочен. Объект не должен заботиться о том, является ли он частью списка. Кроме того, ограничение себя одним списком далеко не является универсальным.

molbdnilo 12.03.2024 09:50

@molbdnilo Извините, приложение требует наличия объектов в списке.

uuu777 12.03.2024 14:40

@ uuu777 Конечно, объекты должны быть в списке. Это не означает, что существует только один список или что вам нужен флаг, чтобы отслеживать, является ли узел частью какого-либо списка или нет.

molbdnilo 12.03.2024 16:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
13
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После обсуждения в комментариях (всем спасибо), кажется, я могу сам ответить на этот вопрос: (1) реализовать правило пяти — это хорошая идея только для поддержки unique_ptr, (2) исходный объект ход не должен быть в списке после его завершения.

Другие вопросы по теме