Метод подкачки с участниками константы

Я хочу реализовать Подкачку () метод для моего класса (давайте назовем это A) сделать оператор копии-и-подкачки = (). Насколько я знаю, подкачиваю метод, должен быть реализован путем свопинга всех членов класса, например:

class A 
{
  public:
    void swap(A& rhv) 
    {
        std::swap(x, rhv.x);
        std::swap(y, rhv.y);
        std::swap(z, rhv.z);
    }
  private:
    int x,y,z;
};

Но что я должен сделать, если у меня есть участник константы? Я не могу назвать станд.:: подкачка для него, таким образом, я не могу кодировать A:: Подкачка ().

Править: На самом деле мой класс немного более сложен. Я хочу Сериализировать и Десериализовать его. Участник константы является частью данных, которые не изменятся (его идентификатор, например) в этом объекте. Таким образом, я думал о записи чего-то как:

class A
{
  public:
    void Serialize(FILE* file) const
    {
        fwrite(&read_a, 1, sizeof(read_a), file);
    }

    void Deserialize(FILE* file) const
    {
        size_t read_a;
        fread(&read_a, 1, sizeof(read_a), file);
        A tmp(read_a);
        this->Swap(tmp);
    }

 private:
   const size_t a;
};

и вызов этот код:

A a;
FILE* f = fopen(...);
a.Deserialize(f);

Я сожалею о такой неопределенной формулировке.

7
задан f0b0s 5 February 2010 в 21:38
поделиться

6 ответов

Я думаю, что фраза обычно используется для обозначения цикла, который повторяется много раз, и который может оказать серьезное влияние на производительность программы - то есть он может использовать много циклов ЦП. Обычно вы слышите эту фразу в обсуждении оптимизации.

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

-121--937652-

Есть хороший пример плотной петли (~ бесконечный цикл) в видео Джон Скит и Тони Пони .

Пример:

while(text.IndexOf("  ") != -1) text = text.Replace("  ", " ");

, который создает плотный цикл, поскольку IndexOf игнорирует символ нулевой ширины Юникода (таким образом, находит два смежных космический), но Replace не игнорирует их (таким образом, не заменяя ни один смежный космический).

В других ответах уже есть хорошие определения, поэтому больше я их не упоминаю.

-121--937653-

После хороших ночей сна я думаю, что лучший ответ - использовать не-const указатель на значение const - после всего этого семантика, которую вы пытаетесь захватить.

5
ответ дан 6 December 2019 в 10:50
поделиться

Я предлагаю вам использовать указатели на экземпляры. Указатели можно поменять местами намного проще, чем данные в классе или структуре .

Единственный способ поменять местами постоянное значение - это создать другой объект или клонировать текущий объект.

Дана структура:

struct My_Struct
{
  const unsigned int ID;
  std::string        name;
  My_Struct(unsigned int new_id)
    : ID(new_id)
  { ; }
};

Насколько я понимаю, вы хотите поменять местами экземпляры чего-то вроде My_Struct выше. Вы можете скопировать изменяемые (неконстантные) члены, но не член const . Единственный способ изменить член const - создать новый экземпляр с новым значением для члена const .

Возможно, вам нужно переосмыслить свой дизайн.

1
ответ дан 6 December 2019 в 10:50
поделиться

f0b0s, хороший принцип проектирования - проектировать объекты так, чтобы они были неизменяемыми . Это означает, что объект не может измениться после создания. Чтобы «изменить» объект, вы должны скопировать объект и обязательно изменить нужные вам элементы.

При этом, в этом случае вам следует использовать конструктор копирования вместо копирования объектов, которые вы хотите поменять местами, а затем фактически поменять местами ссылки на объект. Я понимаю, что было бы заманчиво просто изменить элементы объекта под капотом, но было бы лучше сделать копию объекта и заменить ссылки на этот объект на NEW вместо этого. Это избавит вас от любых неприятностей.

Надеюсь, это поможет.

3
ответ дан 6 December 2019 в 10:50
поделиться

ВАЖНО подумать о том, чтобы не менять членов CONST.

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

0
ответ дан 6 December 2019 в 10:50
поделиться

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

class A 
{
   private:

     struct A_Data {
       int x;
       int y;
       const int z;

       A_Data(int initial_z) : z(initial_z) {}
    };

    std::auto_ptr<A_Data> p_data;

  public:

     A(int initial_z) : p_data(new A_Data(initial_z)) {}

     void swap(A& rhv) {
        std::swap(p_data, rhv.p_data);
     }
};

Это сохраняет значение z постоянным в любом экземпляре внутренних данных объекта A , но вы можете поменять местами внутренние данные двух объектов A (включая значение константы z ) без нарушения константной корректности.

9
ответ дан 6 December 2019 в 10:50
поделиться

Именно поэтому был создан const_cast. Просто не забывайте не отстреливать ногу.

Редактирование: Хорошо, я уступаю - const_cast вообще не был создан для этой проблемы. Это может сработать с вашим компилятором, но вы не можете на это рассчитывать, и если демоны вылетают из ноздрей, пожалуйста, не вините меня.

0
ответ дан 6 December 2019 в 10:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: