自动调用拷贝构造函数情况:
1.用类的一个对象去初始化另一个对象;
cat cat1;
cat cat2(cat1);
2.用类的一个对象去初始化另一个对象的另一种形式(赋值运算符)
cat cat2=cat1;
3.对象作为函数参数传递时,调用拷贝构造函数
f(cat a){}
cat b;
f(b);
4.如果函数的返回值是类的对象,函数调用返回时,调用拷贝构造函数
cat f()
{
cat a;
……
return a;
}
cat b;
b=f();
浅拷贝会出现释放问题:因为都指向同一个对象
浅拷贝是对原数组或对象的引用;
深拷贝是对原数组或对象作一个新的创建,开辟了新的内存
意义:深拷贝可以避免改变新数组或对象时,改变了原数组或对象;
一般的用系统默认的浅拷贝就够用了
如果出现指向堆内存的指针,就需要自定义深拷贝构造函数,为对象创建新的空间,否则会出现野指针。
深拷贝同时复制了资源 和 空间——开辟空间大小 和 内容
这样就不会新旧都指向同一个内存地址
https://zhuanlan.zhihu.com/p/26282765(好文,还需研读)
https://blog.csdn.net/weixin_41910848/article/details/82144671
所谓 深浅拷贝:
对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝。
而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝。
深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。
当数据成员是指针,要做深复制
/*
*深浅拷贝构造函数
*/
#include "pch.h"
#include <iostream>
#include <cstring>
using namespace std;
class A {
public:
A(){
}
A(int age,char* cname) {
this->age = age;
this->name = new char[100];
strcpy(this->name, cname);
}
public:
int age;
char* name;
};
int main()
{
char cname[100] = "hello";
char c = 'K';
A a(10, cname);
A b = a;
cout << "a:" << a.age << " " << a.name << endl;
cout << "b:" << b.age << " " << b.name << endl;
b.age = 1;
b.name[0] = c;
cout << "a:" << a.age << " " << a.name << endl;
cout << "b:" << b.age << " " << b.name << endl;
system("pause");
}
属于浅拷贝,就是后来改变的可以改变初始值,因为两者指针虽然是不同的,但指针所str的地址相同
// TestCopy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
/*
*深浅拷贝构造函数
*/
#include "pch.h"
#include <iostream>
#include <cstring>
using namespace std;
class A {
public:
A(){
}
A(int age,char* cname) {//浅复制构造函数
this->age = age;
this->name = new char[100];
strcpy(this->name, cname);
}
A(A& obj) { //深复制构造函数
this->age = obj.age;
this->name = new char[100];
if (name != 0) {
strcpy(this->name, obj.name);
}
}
~A{
delete str}
public:
int age;
char* name;
};
int main()
{
char cname[100] = "hello";
char c = 'K';
A a(10, cname);
A b = a;
cout << "a:" << a.age << " " << a.name << endl;
cout << "b:" << b.age << " " << b.name << endl;
b.age = 1;
b.name[0] = c;
cout << "a:" << a.age << " " << a.name << endl;
cout << "b:" << b.age << " " << b.name << endl;
system("pause");
}
拷贝构造函数:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
using namespace std;
class complex{
public:
float real_number,imaginary_number;
complex();
complex(complex&);//拷贝构造函数声明
void display()
{
cout<< "复数值:"<<sqrt(pow(real_number,2)+pow(imaginary_number,2)) << endl;
}
};
complex::complex(){
real_number=4;
imaginary_number=3;
}
complex::complex(complex& other){
real_number= other.real_number;
imaginary_number=other.real_number;
}
int main(){
complex c;
cout<<c.real_number<<" "<<c.imaginary_number<<endl;
c. display();
complex c2=c;
cout<<c2.real_number<<" "<<c2.imaginary_number<<endl;
c2.display();
return 0;
}
complex c2=c;//这种格式的拷贝,结果不对
另一种方式:
结果正确
complex c3(c);
c3.real_number=6;
c3.imaginary_number=8;
c3. display();