我试图按照“Professional C++”,第 2 版,第 9 章,第 279 页一书中的示例来理解 C++11 中的新移动构造函数。
这是我的类头文件Spreadsheet.h:
class Spreadsheet
{
public:
Spreadsheet(int inWidth = kMaxWidth, int inHeight = kMaxHeight);
Spreadsheet(const Spreadsheet& src);
Spreadsheet(Spreadsheet&& src);
~Spreadsheet();
int getId() const;
int getWidth() const;
int getHeight() const;
void setCellAt(int x, int y, const SpreadsheetCell& cell);
SpreadsheetCell getCellAt(int x, int y) const;
Spreadsheet& operator=(const Spreadsheet& rhs);
Spreadsheet& operator=(Spreadsheet&& rhs);
private:
bool inRange(int val, int upper) const;
void copyFrom(const Spreadsheet& src);
void moveFrom(Spreadsheet& src);
void freeMemory();
int mWidth, mHeight, mId;
SpreadsheetCell** mCells;
static int sCounter;
const static int kMaxWidth = 100;
const static int kMaxHeight = 100;
};
以下是Spreadsheet.cpp的一些片段:
Spreadsheet::Spreadsheet(Spreadsheet&& src)
{
std::cout << "Move ctor" << std::endl;
moveFrom(src);
}
void Spreadsheet::moveFrom(Spreadsheet& src)
{
mId = src.mId;
mWidth = src.mWidth;
mHeight = src.mHeight;
mCells = src.mCells;
src.mWidth = 0;
src.mHeight = 0;
src.mCells = nullptr;
}
Spreadsheet& Spreadsheet::operator=(Spreadsheet&& rhs)
{
std::cout << "Move assignment" << std::endl;
if (this == &rhs) {
return *this;
}
freeMemory();
moveFrom(rhs);
return *this;
}
void Spreadsheet::freeMemory() {
for (int i = 0; i < mWidth; i++) {
delete [] mCells[i];
}
delete [] mCells;
mCells = nullptr;
}
然后,我在我的main上得到了这个:
std::vector<Spreadsheet> vec;
for (int i = 0; i < 3; i++) {
std::cout << "Iteration " << i << std::endl;
vec.push_back(Spreadsheet(1, 1));
std::cout << vec[i].getId() << std::endl;
std::cout << std::endl;
}
程序输出如下:
Iteration 0 Normal ctor Move ctor 0 Iteration 1 Normal ctor Move ctor Copy ctor 1 Iteration 2 Normal ctor Move ctor Copy ctor Copy ctor 3
我希望只调用所有元素的移动 ctor 而不是复制 ctor,而不仅仅是第一个元素,因为向量会调整自身大小以适应新元素。
我正在使用 clang 3.3-1 和 libc++ 3.3-3 进行编译:
$ clang++ -Wall -g -std=c++11 -stdlib=libc++ -lc++abi \
SpreadsheetTest.cpp Spreadsheet.o SpreadsheetCell.o -o SpreadsheetTest
我无法弄清楚我的实现是否有问题,或者它与std::vector
不使用移动构造函数的实现有关。