C ++ Copy Constructor для массива указателей на объекты - PullRequest
0 голосов
/ 17 октября 2018

Я создал класс, который содержит размер и массив типа Rectangle ** a .правильная инициализация ниже:

C(int size = 1, Rectangle **a = new Rectangle *[1]);

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

C ( const C & other) : size{other.size},  a{size ? new Rectangle[size] : nullptr}
{
    // ....
}

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Чтобы избежать необратимого повреждения мозга, используйте std::vector<Rectangle> в качестве члена.

class C {
public:
    C(const std::vector<Rectangle> &rectangles) : m_rectangles(rectangles) {}
    C(const C &other) : m_rectangles(other.m_rectangles) {}
private:
    std::vector<Rectangle> m_rectangles;
};
0 голосов
/ 17 октября 2018

Вы должны соблюдать правило 0/3/5 .

Правило нуля гласит:

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

RAII контейнеры - хороший инструмент, позволяющий избежать управления ресурсами,Это лучший сценарий для вас:

#include <vector>
struct Rectangle {};

class C
{
    std::vector<Rectangle> _v; // no memory management from C
public:
    size_t size() const { return _v.size(); }
    Rectangle      & operator()(size_t index)       { return _v[index]; }
    Rectangle const& operator()(size_t index) const { return _v[index]; }
};

Если по какой-то причине вам нужно управлять своими ресурсами вручную, вступают в силу правила 3 ​​и 5.

В C ++98, правило из трех состояний:

Если для класса требуется пользовательский деструктор, пользовательский конструктор копирования или пользовательский оператор назначения копирования,почти наверняка требуется все три.

В C ++ 11 и более поздних правилах из пяти заменяет его:

Поскольку присутствиепользовательский деструктор, оператор копирования-конструктора или оператор копирования-назначения предотвращает неявное определение конструктора перемещения, а оператор присваивания перемещения, любой класс для которого требуется семантика перемещения, должен объявлять все пять специальных функций-членов

struct Rectangle {};

struct C
{
    size_t      _size;
    Rectangle*  _data;

    C() : _size(0), _data(nullptr) {}
    C(size_t size) : _size(size), _data(_size == 0 ? nullptr : new Rectangle[_size]) {}
    C(C const& other) : _size(other._size), _data(_size == 0 ? nullptr : new Rectangle[_size])
    {
        std::copy(_data, other._data, other._data + _size);
    }
    C& operator=(C const& other)
    {
        C self = other; // copy construction
        using std::swap;
        swap(*this, self);
        return *this;
    }
    // if necessary: move constructor and move assignment operator
    ~C() { delete _data; }
};
0 голосов
/ 17 октября 2018

Пусть стандартная библиотека сделает всю работу за вас.Использование std::vector<Rectangle> будет безопаснее, проще и надежнее.

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

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