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

《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复制到左边。如果是自赋值,两边相同,因此复制时会访问悬挂指针。
赋值运算符完成了管理动态分配内存的三大例程:析构函数、复制构造函数、赋值运算符。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值