0

I have created a class that contains the size and an array of type Rectangle **a. is the initialization below correct:

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

For the copy constructor I've tried this which (edit: don't know how to complete to copy each pointer of the array into the copy, since each element is also a pointer):

C ( const C & other) : size{other.size},  a{size ? new Rectangle[size] : nullptr}
{
    // ....
}
2
  • 3
    which is giving me errors when you are given errors, the first step is to read the error messages. Commented Oct 17, 2018 at 12:17
  • Read the errors, observe the errors, know the errors, debug the errors and rectify the errors... But it seems that we got none of them from the question... Commented Oct 17, 2018 at 12:18

3 Answers 3

2

Let the standard library do the work for you. Using std::vector<Rectangle> will be safer, simpler and more reliable.

To answer your question, no your copy constructor is not correct as it only creates a new array of the same size and doesn't copy the existing elements into it.

Sign up to request clarification or add additional context in comments.

2 Comments

forgot to mention that I cannot use vectors for this solution
@Anon why? If you can't use std::vector then you'll almost have to implement std::vector yourself to deal with various edge cases
0

To avoid permanent brain damage, use std::vector<Rectangle> as a member.

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;
};

2 Comments

Since the copy constructor is redundant, it could be written as self-documenting code this way for those who like to be explicit: C(C const&) = default;
Also in this, what you really want for the constructor in this particular example is C(std::vector<Rectangle> rectangles) : m_rectangles(std::move(rectangles)) {}
0

You need to respect the rule of 0/3/5.

The rule of zero states:

Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership (which follows from the Single Responsibility Principle). Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.

RAII containers are a good tool to avoid managing resources. This is the best scenario for you:

#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]; }
};

If for some reason you need to manage your resources manually, the rules of 3 and 5 kick in.

In C++98, the rule of three states:

If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.

In C++11 and later, the rule of five replaces it:

Because the presence of a user-defined destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator, any class for which move semantics are desirable, has to declare all five special member functions

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; }
};

2 Comments

can I use copy to copy all the elements even if each element is a pointer to a new Rectangle? I'm implementing the copy assignment after this, thanks :)
If you need a 2D container, use an underlying 1D vector or array and overload operator()(size_t x, size_t y).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.