我最近重新访问了此处看到的复制构造函数、赋值运算符、复制交换惯用语: 什么是复制和交换惯用语? 和许多其他地方——
上面的链接是一个很好的帖子 - 但我还有一些问题 - 这些问题在很多地方得到了回答,在 stackoverflow 和许多其他网站上,但我没有看到很多一致性 -
1-您是否应该在复制构造函数中为深复制分配新内存try
的catch
区域周围?(我已经看到了两种方式)
2 - 关于复制构造函数和赋值运算符的继承,什么时候应该调用基类函数,什么时候这些函数应该是虚拟的?
3 - std::copy
在复制构造函数中复制内存的最佳方法是什么?我已经看到它memcpy
,并且看到其他人说memcpy
地球上最糟糕的事情。
考虑下面的示例(感谢所有反馈),它提示了一些其他问题:
4 - 我们应该检查自我分配吗?如果是在哪里
5 - 题外话,但我已经看到交换用作:
std::copy(Other.Data,Other.Data + size,Data);
应该是:
std::copy(Other.Data,Other.Data + (size-1),Data);
如果交换从“第一个到最后一个”并且第 0 个元素是 Other.Data?
6 - 为什么注释掉的构造函数不起作用(我不得不将大小更改为 mysize) - 假设这意味着无论我编写它们的顺序如何,构造函数总是首先调用分配元素?
7 - 对我的实施还有其他意见吗?我知道代码没用,但我只是想说明一点。
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : a(0), b(new int) {} //We Always Allocate the int
TBar(TBar const &Other) : a(Other.a), b(new int)
{
std::copy(Other.b,Other.b,b);
*b = 22; //Just to have something
}
virtual ~TBar() { delete b;}
};
class TSuperFoo : public TBar
{
public:
int* Data;
int size;
//Swap Function for copy swap
void swap (TSuperFoo &One, TSuperFoo &Two)
{
std::swap(static_cast<TBar&>(One),static_cast<TBar&>(Two));
std::swap(One.Data,Two.Data);
std::swap(One.size,Two.size);
}
//Default Constructor
TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[mysize]) {}
//TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[size]) {} *1
//Copy Constructor
TSuperFoo(TSuperFoo const &Other) : TBar(Other), size(Other.size), Data(new int[Other.size]) // I need [Other.size]! not sizw
{
std::copy(Other.Data,Other.Data + size,Data); // Should this be (size-1) if std::copy is First -> Last? *2
}
//Assignment Operator
TSuperFoo& operator=(TSuperFoo Other)
{
swap(Other,(*this));
return (*this);
}
~TSuperFoo() { delete[] Data;}
};