Как члены массива C++ обрабатываются в функциях управления копированием?

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

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 или что?


person fredoverflow    schedule 12.11.2010    source источник
comment
Это не совсем C, а (в основном) C++.   -  person Dervin Thunk    schedule 12.11.2010
comment
@DervinThunk Я изменил название вопроса с C на C++   -  person jfritz42    schedule 20.05.2016


Ответы (2)


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

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

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

Скопируйте задание:

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

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

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

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
  • Из первой строки результата видно, что хоть что-то скопировано (это либо элементы в массиве, либо скопирован указатель массива).
  • Из следующих двух строк видно, что изменение копии назначенных объектов и копирование массива созданных объектов не изменило исходный массив. Следовательно, мы делаем вывод, что вместо указателя на массив были скопированы элементы.

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

person tartaruga_casco_mole    schedule 15.11.2018