class
Table{
Name * p;
size_t sz;
publish:
Table(size_t s = 15 ){p = new Name[sz = s];}
~ Table(){delete[]p ;}
......
}
void h()
{
Table t1;
Table t2 = t1;
Table t3;
t3 = t2;
}
Name * p;
size_t sz;
publish:
Table(size_t s = 15 ){p = new Name[sz = s];}
~ Table(){delete[]p ;}
......
}
void h()
{
Table t1;
Table t2 = t1;
Table t3;
t3 = t2;
}
在h()结束时,默认构造函数调用了2次,而析构函数被调用了3次,为何?
Table t1; 调用1次默认构造函数
Table t2 = t1;默认的对象的赋值操作,按成员赋值,其中关于指针p,仅仅是将t1.p赋值给t2.p,即t2.p = t1.p,并无内存分配。对象t1和t2的p指针均指向同一块内存。
Table t3; 调用1次默认构造函数
t3 = t2; 原t3.p指针被t2.p覆盖,此时t3.p同样指向对象t1和t2的p指针的同一块内存。注意:t3原分配给p的内存由于没有指针指向,无法利用,造成存储浪费。
h()结束,对象t1,t2,t3的析构函数调用,此时对t1,t2,t3的指针p所指的同一块存储进行了三次删除,非常危险,导致的结果是无发预料的,很可能灾难性的。
因此明确定义类的复制构造函数(拷贝构造函数)和赋值预算可避免这样的错误。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
Table::Table (
const
Table
&
t)
{
p = new Name[sz = t.sz];
for ( int i = 0 ;i < sz;i ++ ) p[i] = t.p[i];
}
Table & Table:: operator = ( const Table & t)
{
if ( this !=& t){
delete []p;
p = new Name[sz = t.sz];
for ( int i = 0 ;i < sz;i ++ ) p[i] = t.p[i];
}
return * this ;
}
{
p = new Name[sz = t.sz];
for ( int i = 0 ;i < sz;i ++ ) p[i] = t.p[i];
}
Table & Table:: operator = ( const Table & t)
{
if ( this !=& t){
delete []p;
p = new Name[sz = t.sz];
for ( int i = 0 ;i < sz;i ++ ) p[i] = t.p[i];
}
return * this ;
}
详见《C++程序设计语言-特别版》page 219