C++拷贝构造函数的陷阱

拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象,拷贝一份副本。

不过看似简单的东西,实际不注意的话就会产生问题!

#include

using namespace std;

class CExample

{

public:

int a,b,c;

char *str;

public:

//构造函数

CExample(int tb)

{

a = tb;

b = tb+1;

c = tb+2;

str=(char *)malloc(sizeof(char)*10);

strcpy(str,“123456789”);

cout<<"creat: "<<endl;

}

//析构函数

~CExample()

{

cout<< "delete: "<<endl;

}

void Show ()

{

cout<<a<<endl;

}

//拷贝构造

//CExample(const CExample& C)

//{

// str=(char *)malloc(sizeof(char)*10);

// strcpy(str,C.str);

// cout<<“copy”<<endl;

//}

};

//全局函数,传入的是对象

void g_Fun(CExample C)

{

C.a=0;C.b=0;C.b=0;

strcpy(C.str,“aaabbbccc”);

cout<<“test”<<endl;

}

int main()

{

CExample test(1);

cout<<“str:”<<test.str<<" a="<<test.a<<" b="<<test.b<<" c="<<test.c<<endl;

g_Fun(test);//传入对象

cout<<“str:”<<test.str<<" a="<<test.a<<" b="<<test.b<<" c="<<test.c<<endl;

getchar();

return 0;

}
在这里插入图片描述

这个结果似乎出乎了我们的预料,作为形式参数 test对象被修改了,同时是test.str的部分被修改了,test的整数成员变量没有被修改!

咱们先了解一下系统默认的拷贝构造函数,因为类中没有写自己的拷贝构造函数,所以调用的是默认的拷贝构造函数。

Thinking in c++:对于简单结构,编译器会自动生成一个缺省的,就是位拷贝(bitcopy)。

对于比较复杂的类型,编译器就会自动生成一个缺省的拷贝构造函数。

class CExample

{

int a,b,c;

};

这就是一个简单结构的类,位拷贝,就是按对象在内存中的二进制进行拷贝,对于不涉及指针等类型的时候,位拷贝是比较不错的拷贝方法。

但是,要是一个类中有指针类型的时候,如

class CExample

{

int a,b,c;

char *str;

};

位拷贝就会把指针地址拷贝了一下,话句话说,这里只进行了“浅拷贝”,一旦副本里涉及到指针的操作,必然就会影响到原始对象的成员变量,这就是导致,上面代码中对象的整数变量没被修改(对整数变量的位拷贝其实就是一种“深拷贝”),而str所指的对象被修改的原因。·

那么该如何防止对副本的修改影响原始对象呢?

答案是用户自定义拷贝构造函数!

发布了243 篇原创文章 · 获赞 4 · 访问量 3733

猜你喜欢

转载自blog.csdn.net/it_xiangqiang/article/details/105177037