具有动态分配数组的类的C ++拷贝构造函数
从C ++开始(几天后),我带着C背景。
我有一个类,主要是一个指向int数组的指针,其代码如下:
class Array
{
private:
int * _arr;
int _size;
public:
Array();
Array(int size);
Array(const Array& obj); // copy constructor
~Array();
void readInValues();
void mult(int num);
void add(int num);
void printArray();
};
_arr是一个指向int数组的指针,当使用复制构造函数创建新实例时,我会在堆上创建一个新的int数组(我认为)。 在复制构造函数中:
Array::Array( const Array & obj )
{
_arr = new int[_size];
for(int i=0;i<_size;i++)
*_arr[i] = *obj._arr[i];
}
我做的第一件事是为新数组分配内存(_size是一个原始类型,因此据我所知可以自动复制)。 接下来我想要做的就是使用循环复制数组本身。 这部分编译失败说非法间接。 我不知道为什么...
这个:
Array::Array( const Array & obj )
{
_arr = new int[_size];
for(int i=0;i<_size;i++)
*_arr[i] = *obj._arr[i];
}
可能是这样的:
Array::Array( const Array & obj )
: _arr(obj._size ? new int[obj._size] : nullptr)
, _size(obj._size)
{
if (_arr)
std::copy(obj._arr, obj._arr+_size, _arr);
}
具体来说,请注意使用初始化程序列表。 其他值得一提的事情:
不要使用具有前导下划线的标识符。 除了使代码成为阅读的王室之外,您可以快速找到使用由实现保留的标识符。 情况并非如此,但我敢打赌,这并非意图。
你还需要一个赋值操作符来完成三法则。 值得庆幸的是,一个体面的复制构造函数使这个微不足道。
不要这样做。 这就是为什么,在设计决策中,由于极度的哀叹和大量的牙齿问题,已经过时的全能C ++标准委员会已经如此选择了使用std::vector<>
来保佑我们。 如果你要这样学习,那很好。 一旦你拥抱标准的图书馆和所有的罪恶乐趣,你最终会学到的是很少有你需要的。
如果这是一个学习练习,荣誉,并且乐意忽略上述(3)。 对于(2),现在您可以使用复制/交换习惯用法,因为您拥有合理的copy-ctor:
Array& Array::operator =(Array obj) // value-param intentional
{
std::swap(_arr, obj._arr);
std::swap(_size, obj._size);
return *this;
}
祝你好运。
_size
没有初始值,因为在使用它之前您没有将它作为参数或初始化在其他地方传递。
另外,不要做*_arr[i] = *obj._arr[i];
它没有任何意义,因为arr[i]
本身意味着*(arr+i)
。
做:
_arr[i] = obj._arr[i];
当你这样做时,你应该没问题
Array::Array( const Array & obj ):
_size(obj._size)
{
_arr = new int[_size];
for(int i=0;i<_size;i++)
_arr[i] = obj._arr[i];
}
在第二行你会得到初始化列表,阅读这个http://www.cprogramming.com/tutorial/initialization-lists-c++.html
关键是,当你写一个自定义拷贝构造函数时,只有你明确说你拷贝的东西才会被拷贝。 复制构造函数将首先为所有成员调用默认的initilizer,除非您使用初始化值。
另外,性能的一个小提示可能是,你看过memcpy吗? http://www.cplusplus.com/reference/cstring/memcpy/它可能更有效:D
我注意到的另一件事是你取消引用* _arr [i],它不是指针,而是对值的引用。
编辑有人注意到,我的更好实际上并没有更好。 我改变了它。
链接地址: http://www.djcxy.com/p/72921.html上一篇: C++ copy constructor for class with dynamically allocated array