值传递
1 void Lswap(int a,int b){
2 int tem = a;
3 a = b;
4 b = tem;
5 }
main()中:
1 int a=3;
2 int b=7;
3 void Lswap(a,b);
值传递三种方式:
1、对象需要通过另外一个对象进行初始化
2、对象以值传递的方式传入函数参数
3、对象以值传递的方式从函数返回
值传递三种方式举例:
1、对象需要通过另一个对象进行初始化
1 People p;
2 p.setweight(8.0);
3 cout<<p.setweight()<<endl;
4 People p2(p);//执行拷贝构造函数
5 cout<<p2.getweight()<<endl;
2、对象以值传递的方式传入函数参数
1 void printPeople(People p) {//调用拷贝构造函数
2 cout<<&p<<" "<<p.getAge()<<" "<<p.getweight()<<endl;
3 }
4 People p;
5 p.setweight(8.0);
6 printPeople(p);
3、对象以值传递的方式从函数返回
1 People getPeople(){
2 People p;
3 p.setweight(8.0);
4 return p;
5 }
6 int main(){
7 People p = getPeople();
8 cout<<p.getweight()<<endl;
9 return 0;
10 }
浅拷贝
所有对象都会默认生成一个拷贝构造函数,默认拷贝构造函数就是浅拷贝。
浅拷贝只是简单地将成员拷贝一份,当有指针成员时,可能出现重复释放。
系统会默认生成一个浅拷贝,下面是手写浅拷贝代码:
1 class A {};
2 struct NODE {
3 int arr[20];
4 double d;
5 char* str;
6 A t;
7 NODE() {
8 str = (char*)malloc(20);
9 }
10 ~NODE() {
11 free(str);
12 }
13 NODE(const NODE& other):d(other.d),str(other.str),t(other.t) {
14 //拷贝构造函数的形式
15 memcpy(arr, other.arr, 20 * sizeof(int));
16 cout<<"调用了拷贝构造"<<endl;
17 }
18 };
19 void func(NODE n) {
20 cout << n.d << endl;
21 }
22 void func(int* arr) {//地址传递
23
24 }
25 int main() {
26 int arr[600];
27 func(arr);
28 NODE n;//调用默认构造函数
29 n.d = 23.53;
30 func(n);//发生值传递时才会调用默认拷贝函数(浅拷贝)
31 return 0;
32 }
上面代码会报错,因为NODE里有指针成员str,会出现重复释放空间,也就是free(str)两次。
新旧指针指向同一空间
深拷贝
深拷贝技术:重写拷贝构造函数,把会重复释放的部分让它们分别拥有自己的空间,也就是申请两个空间,分别给新旧地址。
1 struct NODE {
2 int arr[20];
3 double d;
4 char* str;
5 NODE() {
6 str = (char*)malloc(20);
7 }
8 ~NODE() {
9 free(str);
10 }
11 NODE(const NODE& other) :d(other.d), str(other.str) {
12 //拷贝函数的形式
13 this->str = (char*)malloc(20);
14 memcpy(str,other.str,20);
15 memcpy(arr,other.arr,20*sizeof(int));
16 cout << "调用了拷贝构造" << endl;
17 }
18 };
19 void func(NODE n) {
20 cout << n.d << endl;
21 }
22 void func(int* arr) {//地址传递
23
24 }
25 int main() {
26 int arr[600];
27 func(arr);
28 NODE n;//调用默认构造函数
29 n.d = 23.53;
30 func(n);//发生值传递时才会调用默认拷贝函数
31 return 0;
32 }
新旧指针分别申请空间
阻止拷贝构造
1、使用对象时不值传递,而使用指针或引用
2、私有化拷贝构造