《C++高级编程》读书笔记(三)

来源:互联网 发布:js random 编辑:程序博客网 时间:2024/06/05 09:54
《C++高级编程》读书笔记(三)


处理复制以及赋值
        在用指针动态为对象分配内存,直接将源对象直接复制到目的对象时会发生悬挂指针的问题。
       
void printspreadsheet(spreadsheet s){   //code commit for brevity}int main(){      spreadsheet s1(4,3);       printspreadsheet(s1);}
在这段代码中,为s1指针分配了一部分内存,调用printspreadsheet(s1)函数后,s指针也指s1指向的内存,如果修改了s指针所指内存,例如释放了这部分内存,则s1也失去内存,s1为悬挂指针。
所以,依赖C++默认的复制构造函数或者复制运算符未必是个好主意。
无论什么时候在类中动态分配了内存,都应该编写自己的复制构造函数以及赋值运算符,以提供深层次的内存复制。

深层次的复制构造函数
spreadsheet::spreadsheet(const spreadsheet & src){    mwidth= src.mwidth;    mheight=src.mheight;    mcell= new spreadsheet * [mwidth];    for(int i=0;i<mwidth;i++){    mcell[i]=new spreadsheet[mheight];    for(int i=0;i<mwidth;i++) {    for(int j=0;j<mheight;j++)         mcell[i][j]=src.mcell[i][j];      }}
深层次的赋值运算符
Spreadsheet& Spreadsheet::operator=(const Spreadsheet& rhs){  // check for self-assignment  if (this == &rhs) {    return *this;  }  // free the old memory  for (int i = 0; i < mWidth; i++) {    delete [] mCells[i];  }  delete [] mCells;  mCells = nullptr;  // copy the new memory  mWidth = rhs.mWidth;  mHeight = rhs.mHeight;  mCells = new SpreadsheetCell* [mWidth];  for (int i = 0; i < mWidth; i++) {    mCells[i] = new SpreadsheetCell[mHeight];  }  for (int i = 0; i < mWidth; i++) {    for (int j = 0; j < mHeight; j++) {      mCells[i][j] = rhs.mCells[i][j];    }  }  return *this;}
在任何赋值运算符中,第一行永远是自赋值检测
自赋值检测不仅是为了效率,而且是为了正确性。因为如果删除了前面的自赋值检测,自赋值的时候代码很可能会崩溃,因为代码的第二步删除了左边对象的mcell,然后从将右边的mcell复制到左边。如果是自赋值,两边相同,因此复制时会访问悬挂指针。
赋值运算符完成了管理动态分配内存的三大例程:析构函数、复制构造函数、赋值运算符。


0 0
原创粉丝点击