0

我试图按照“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不使用移动构造函数的实现有关。

4

0 回答 0