2009-02-24 3 views
4

Я изучаю экзамен по среднему экзамену. Возникает вопрос о настройке массива динамически и, возможно, создании конструктора копирования, деструктора и перегрузки оператора присваивания. Можете ли вы проверить, правильно ли я. Также я не понимаю, что означает перегрузка оператора присваивания. Можете ли вы мне помочь?Динамический массив ... копия конструктор, деструктор, перегруженный оператор присваивания

class A 
{ 
int* myArray; //basically I created a pointer called myArray, 
A()    //are my copy constructors correct? A(), and A(int size)? 
{ 
    myArray = 0; 
} 
A(int size) 
{ 
    myArray = new int[size]; 
} 
~A()    // I think my destructor is correct 
{ 
    delete [] myArray; 
} 

Вы можете проверить мой код пожалуйста? Также как я могу перегрузить оператор присваивания?

Заранее спасибо.

+0

также предположим, что конструктор принимает параметр int, float или no. В каждом случае элементы инициализируются разными значениями. Возможно ли иметь только один конструктор? Или мне нужны три разных конструктора? – user69699

ответ

6

Конструктор копирования используется для создания объекта на основе экземпляра другого экземпляра того же типа. У вас их нет. Вы можете определить его с помощью кода, как это:

A(const A &other) 
{ 
    myArray = new int[other._size]; 
    _size = other._size; 
    memcpy(myArray, other.myArray, sizeof(int) * _size); 
} 

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

Оператор перегружено задание должен выглядеть следующим образом:

const A &operator=(const A &other) 
{ 
    if(this == &other) return *this; // handling of self assignment, thanks for your advice, arul. 
    delete[] myArray; // freeing previously used memory 
    myArray = new int[other._size]; 
    _size = other._size; 
    memcpy(myArray, other.myArray, sizeof(int) * _size); 
    return *this; 
} 

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

+1

Оператор присваивания также должен обрабатывать самоопределение. – arul

+2

В общем, это хорошая идея, использовать идиому copy-and-swap в операторах присваивания - http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap – Paulius

0

Частичный ответ: перегрузка функции предполагает создание различных версий этой функции, которые принимают разные числа или виды аргументов. Поэтому перегрузка оператора присваивания будет включать в себя создание нескольких функций для оператора присваивания, которые позволяют назначать объекты разных типов переменной типа A.

7

Вы правильно определили 2 перегруженных конструктора и деструктор.

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

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

Проблемы с автоматически генерируемым неявным конструктора копированием в вашем конкретном случае является то, что он будет выполнять только неполную копию MyArray, где она разделяет то же значение указателя, но не выделена своему участка памяти туАггау.

Это означает, что если вы удалите myArray в исходном объекте, это повлияет на копию, которая скорее всего не то, что вы хотите.

Определение явного конструктора копирования, как это поможет:

A(const A& copy) 
    : _size(copy.size), myArray(new int[copy.size]) 
{ 
    // #include <algorithm> for std::copy 
    std::copy(copy.data, copy.data + copy.size, data); 
} 

(Источник: скопированные из Wikipedia)

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

Edit: От this article:

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

3

при работе с объектом копированием и динамическим распределением памяти это хорошая идея использовать своп вспомогательной функции

A(const A& other) 
    : myArray(0) 
    , _size(0) 
{ 
    if(this != &other) { 
     A my_tmp_a(other._size); 
     std::copy(&other[0], &other[other._size], &my_tmp_a[0]); 
     swap(my_tmp_a); 
    } 
} 

const A& operator=(const A& other) 
{ 
    if(this == &other) return *this; 
    A my_tmp_a(other._size); 
    std::copy(&other[0], &other[other._size], &my_tmp_a[0]); 
    swap(my_tmp_a);  
    return *this; 
} 

void swap(const A& other) { 
    int* my_tmp_array = this.myArray; 
    this.myArray = other.myArray; 
    other.myArray = my_tmp_array; 
    int my_tmp_size = this._size; 
    this._size = other._size; 
    other._size = my_tmp_size; 
} 
+0

+1 для использование копирования и замены в операторе присваивания. – Paulius

+0

Не нужно замедлять выполнение с помощью теста, что будет бесполезно 99,999% времени. Идиомы с копией и заменой более чем достаточно. –

1

Пожалуйста, убедитесь, что определить три функции, если вы хотите, чтобы определить один из них. Его называют all или none rule Это: 1) копировать конструктор. 2) оператор присваивания. 3) деструктор.

Смежные вопросы