当类的成员含有指针时,需要特别注意其拷贝构造函数,默认的考构只会将新对象的成员指针指向原对象的指针所指处
class s12{
public:
s12(int a=2):i(a){
cout<<"in s12 constructor\n";
}
// s12( const s12 &obj){
// cout<<"in s12 copy constructor\n";
// }
~s12(){
cout<<"in s12 destructor and i= "<<i<<endl;
}
int i;
int *p;
};
|
将我们的考构去掉,因为它没有复制的功能,用系统默认的考构。
int main(void){
s12 obj1;
obj1.p=&obj1.i;
cout<<"obj1.p->i = "<<*obj1.p<<endl;
s12 obj2(obj1);
cout<<"obj2.p->i = "<<*obj2.p<<endl;
cout<<"obj1.p: "<<obj1.p<<" obj2.p: "<<obj2.p<<endl;
cout<<"&obj1.p: "<<&obj1.p<<" &obj2.p:"<<&obj2.p<<endl;
cout<<"&obj1.i: "<<&obj1.i<<endl;
cout<<"end main\n";
}
|
运行结果
in s12 constructor
obj1.p->i = 2
obj2.p->i = 2
obj1.p: 0x22ff68 obj2.p: 0x22ff68
&obj1.p: 0x22ff6c &obj2.p:0x22ff5c
&obj1.i: 0x22ff68
end main
in s12 destructor and i= 2
in s12 destructor and i= 2
|
obj1与obj2的成员指针p均指向obj1的成员i,而
obj1.p与
obj2.p其本身的地址是不同的,他们属于不同的对象,在内存中存储的位置当然也就不同。
修改*obj2.p,也就是修改了obj1.i,这容易出现混乱,尤其当是obj1.p指向的内容是new出来的,delete obj2.p时,obj1.p指向的内存被释放了,它成了悬垂指针。
可以引入技术器来完善拥有指针成员的类的拷贝构造函数,计数器表示当前对象的个数,当期为零时,释放指针所指向的内存,COM组件的就是这样。
或者将指针按普通“变量”来对待,在构造函数中为其new出空间,考构中同样new出新空间,这样就可以方便地将老对象的指针delete了。对这样的类,重载赋值运算符时就不用new了,直接将指针接触引用再复制即可。
阅读(653) | 评论(0) | 转发(0) |