Копировать конструктор c ++ странно себя вести? - PullRequest
2 голосов
/ 17 марта 2012

Привет, у меня есть класс, который включает в себя массив, я не пропускаю его через конструктор моего класса (может здесь что-то не так?) Массив только что определен в классе, а затем инициализирован в методе чтения.

Но в основном я делаю экземпляр класса как:

myClass myClass1;

Затем выполните:

myClass1 = myClass2;

Теперь я использую метод пузырьковой сортировки для первого экземпляра класса, например:

MyClass1.sort();

Теперь, когда я записываю оба этих экземпляра в текст после сортировки, они оба сортируются?

Я прочитал мелкие и глубокие копии, но не могу понять, почему метод, вызванный после мелкой копии, приведет к сортировке их обоих? Это ожидаемое поведение?

чуть больше информации:

В моем классе я просто определяю массив как:

static string myArray[5];

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

Ответы [ 2 ]

3 голосов
/ 17 марта 2012

Как определяется / создается ваш массив? Если вы создаете его с помощью new и ссылаетесь на него указателем, вам понадобится специальный конструктор копирования, создающий глубокую копию (т.е. создающий новый экземпляр массива и копирующий его содержимое). Конструктор копирования по умолчанию будет выполнять только поверхностное копирование, поэтому оба экземпляра будут использовать одну и ту же память (т. Е. Оба указателя указывают на один и тот же массив в куче).

Это будет работать с конструктором копирования по умолчанию:

class myclass {
    char text[256];
}

Это не будет работать с конструктором копирования по умолчанию (по крайней мере, не так, как ожидалось):

class myclass {
    char *text;
    myclass() : text(new char[256]) {}
    ~myclass() { delete [] text; }
}

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

class myclass {
    static char text[256];
}

Конструктор копирования для второго случая может выглядеть следующим образом (обратите внимание, это упрощено и не проверяет допустимые значения и тому подобное):

myclass(const myclass &base) : text(new char[256]) { strcpy(text, base.text); }

Общее правило: Использую ли я какой-либо элемент указателя, которому присваивается возвращаемое значение некоторого new? Если это так, напишите конструктор копирования. Если нет, то он использует его по умолчанию (если у вас нет других причин).

2 голосов
/ 17 марта 2012

В моем классе я просто определяю массив следующим образом:

static string myArray[5];

Должен ли я объявить его в заголовке, так как он только объявлен в файле cpp?Поскольку он все еще копирует оба.

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

class MyClass1 {
    // other things...
    string myArray[5];
};

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

...