我创建了一个包含大小和类型数组的类 矩形** a 。下面的初始化正确吗:
C(int size = 1, Rectangle **a = new Rectangle *[1]);
对于复制构造函数,我尝试了以下操作(编辑:不知道如何完成将数组的每个指针复制到副本中的操作,因为每个元素也是一个 指针):
C ( const C & other) : size{other.size}, a{size ? new Rectangle[size] : nullptr}
{
// ....
}
答案 0 :(得分:2)
让标准库为您完成工作。使用std::vector<Rectangle>
将更安全,更简单,更可靠。
要回答您的问题,没有一个复制构造函数是不正确的,因为它只会创建一个相同大小的新数组,并且不会将现有元素复制到其中。
答案 1 :(得分:0)
为避免对大脑造成永久性损害,请使用[[1, 10, 9, 8]
[2, 0, 0, 7]
[3, 4, 5, 6]]
作为成员。
std::vector<Rectangle>
答案 2 :(得分:0)
您需要尊重the rule of 0/3/5。
零规则状态:
具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权(遵循“单一职责原则”)。其他类不应具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符。
RAII containers是避免管理资源的好工具。这是最适合您的方案:
#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; }
};