Как обрабатываются члены массива C ++ в функциях управления копированием? - PullRequest
30 голосов
/ 12 ноября 2010

Это то, что я задавался вопросом в течение долгого времени. Возьмите следующий пример:

struct matrix
{
    float data[16];
};

Я знаю, что конструктор и деструктор по умолчанию делают в этом конкретном примере (ничего), но как насчет конструктора копирования и оператора назначения копирования?

struct matrix
{
    float data[16];

    // automatically generated copy constructor
    matrix(const matrix& that) : // What happens here?
    {
        // (or here?)
    }

    // automatically generated copy assignment operator
    matrix& operator=(const matrix& that)
    {
        // What happens here?

        return *this;
    }
};

Это включает std::copy или std::uninitialized_copy или memcpy или memmove или что?

Ответы [ 2 ]

41 голосов
/ 12 ноября 2010

Это то, что стандарт говорит в 12.8 (Копирование объектов класса). Копирование конструкции:

Каждый подобъект копируется способом, соответствующим его типу:

  • если подобъект имеет тип класса, используется конструктор копирования для класса;
  • если подобъект является массивом, каждый элемент копируется способом, соответствующим типу элемента;
  • если подобъект скалярного типа, используется встроенный оператор присваивания.

Копирование:

Каждый подобъект назначается способом, соответствующим его типу:

  • если подобъект имеет тип класса, используется оператор присвоения копии для класса (как будто с помощью явной квалификации; то есть игнорирование любых возможных виртуальных переопределяющих функций в более производных классах);
  • если подобъект является массивом, каждому элементу присваивается способ, соответствующий типу элемента;
  • если подобъект скалярного типа, используется встроенный оператор присваивания.
1 голос
/ 15 ноября 2018

Оба копируют элементы в массиве (вместо того, чтобы ничего не делать или копировать указатель).

struct X
{
    char data_[100];
};


int main () 
{
    X orig, copy_assign;
    orig.data_[10] = 'a';
    copy_assign = orig;
    X copy_constructor(orig);
    printf("orginal10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
    copy_assign.data_[10] = 'b';
    printf("original10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
    copy_constructor.data_[10] = 'c';
    printf("original10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
    return 0;
}

результаты выполнения:

orginal10:a, copy_assign10:a, copy_constructor10:a
original10:a, copy_assign10:b, copy_constructor10:a
original10:a, copy_assign10:b, copy_constructor10:c
  • Из первой строки результата, мы можем видеть, что по крайней мере что-то было скопировано (это либо элементы в массиве, либо был скопирован указатель массива).
  • Из следующих двух строк мы можем видеть, что при изменении копии назначаются объекты и копиямассив построенных объектов не изменил исходный массив.Поэтому мы заключаем, что элементы были скопированы вместо указателя массива.

Надеюсь, этот пример понятен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...