类一定要定义拷贝构造函数,特别是在类成员含有指针的情况(不论指针是何种类型),安全!!!

来源:互联网 发布:大华淘宝客助手 编辑:程序博客网 时间:2024/06/06 21:40

举例说明一个未定义拷贝构造函数产生的非常诡异的现象

using namespace std;
class people 
{
private:
char *name;
int age;
public:
people(char *namestr,int i);
/*people( const people& temp);*/
~people();
char *getname()const;
int getage()const;
};
people::people(char *namestr,int i)
{   
int len=strlen(namestr);
name=new char[len+1];
strcpy(name,namestr);
    *(name+len)='\0';
age=i;
}
//people::people( const people& temp)
//{
// char* tempName=temp.getname();
// int   tempAge=temp.getage();
// int len=strlen(tempName);
// name=new char[len+1];
// strcpy(name,tempName);
//    *(name+len)='\0';
// age=tempAge;
//
//}
people::~people()
{
delete name;
}
char *people::getname()const
{
return name;
}
int people::getage()const
{
return age;
}
void display(people  x)
{
cout<<"people\'s name: "<<x.getname()<<endl;
cout<<"people\'s age: "<<x.getage()<<endl;
}


int main()
{
people p("xieyi",30);
display(p);
return 0;
}

说明:

类对象作为形参,

display(p);必须调用拷贝构造函数,对形参进行赋值,如果未定义,则调用默认的拷贝构造函数进行赋值,这里的类成员是char*,

int,理论上默认构造函数是可以的,char*只赋值指针。

进过我单步调试,也是没有问题的。

即时窗口的输出如下:

p.getname()
0x002e49c8 "xieyi"

p.getage()
30

x.getname()
0x002e49c8 "xieyi"
x.getage()
30

说明默认构造函数可以很好的运行,也是可以输出正确结果的。

但是运行到最后,在输出正确的结果后会产生异常:

Debug Assertion Failed!

_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)


解决方法:

还是乖乖定义拷贝构造函数:

class people 
{
private:
char *name;
int age;
public:
people(char *namestr,int i);
people( const people& temp);
~people();
char *getname()const;
int getage()const;
};
people::people(char *namestr,int i)
{   
int len=strlen(namestr);
name=new char[len+1];
strcpy(name,namestr);
    *(name+len)='\0';
age=i;
}
people::people( const people& temp)
{
char* tempName=temp.getname();
int   tempAge=temp.getage();
int len=strlen(tempName);
name=new char[len+1];
strcpy(name,tempName);
    *(name+len)='\0';
age=tempAge;


}
people::~people()
{
delete name;
}
char *people::getname()const
{
return name;
}
int people::getage()const
{
return age;
}
void display(people  x)
{
cout<<"people\'s name: "<<x.getname()<<endl;
cout<<"people\'s age: "<<x.getage()<<endl;
}


int main()
{
people p("xieyi",30);
display(p);
return 0;
}

就不会出错!!


除了这种错误,还可能出现的错误是

指针在逻辑上没错,但是指针的解引用得到的值跟逻辑上应该得到的值是不一样的


总结:任何类一定要定义拷贝构造函数,特别是有指针成员存在的情况,不然容易出现各种问题。。。


0 0