class Human{
public:
int getage();
string getname();
int getcount();
Human(); //默认构造函数
Human(int age, string name); //自定义的重载构造函数
Human(const Human& other); //拷贝构造函数
Human& operator=(const Human& other); //赋值构造函数
~Human(); //析构函数
void test();
void setaddr(const char *newaddr);
const string getaddr();
private:
int age;
string name;
static int count;
char *addr;
};
Human::Human() {
age = 18;
name = "unknown";
}
Human::Human(int age, string name) { //重载构造函数
this->age = age;
this->name = name;
addr = new char[10];
strcpy_s(addr, 10, "china");
count++;
}
Human::Human(const Human& other) { //拷贝构造函数 Human h2=h1时调用,在声明时就直接构造了,是深拷贝
cout<<"调用拷贝构造函数"<<endl;
this->age = other.age;
this->name = other.name;
this->addr = new char[10];
strcpy_s(this->addr, 10, other.addr);
count++;
}
Human& Human::operator=(const Human& other) { //复制构造函数 Human h2; h2=h1;定义和构造使分开的
this->age = other.age;
this->name = other.name;
this->addr = new char[10];
strcpy_s(this->addr, 10, other.addr);
count++;
return *this;
}
void Human::test() {
cout << age <<"--" << name <<"--" << count<<"--"<<addr << endl;
}
void Human::setaddr(const char *newaddr) {
this->addr = new char[10];
strcpy_s(this->addr, 10, newaddr);
}
void test1(Human man) {
cout <<"test1 "<< man.getage() << endl;
}
void test2(Human& man) { //不会调用拷贝构造函数,此时没有没有构造新的对象
cout << "test2 " << man.getage() << endl;
}
Human test3(Human& man) {
cout << "test3 " << endl;
return man;
}
Human& test4(Human& man) {
cout << "test4 " << endl;
return man;
}
int main() {
Human h1(24, "yezi"); //调用重载构造函数
Human h2 = h1; //调用拷贝构造函数 Human h2(h1)这个格式也可以
Human h3;
h3 = h1; //调用赋值构造函数 拷贝和赋值区别是,一个在创建时就赋值,一个是先声明了再赋值。
// 如果不手动定义拷贝构造和赋值构造函数,那么会自动生成这两个函数,但是使用的是浅拷贝,自定义就是深拷贝
h1.setaddr("thai");
h1.test();
h2.test();
h3.test();
cout << "*****************" << endl;
//什么时候调用拷贝构造函数
//1. 调用函数时,实参是对象,形参不是引用类型,如果函数的形参是引用类型,就不会调用拷贝构造函数
//2. 函数的返回类型是类,而且不是引用类型
//3. 对象数组的初始化列表中,使用对象
test1(h1); // 调用拷贝构造函数
test2(h1); // 不会调用拷贝构造函数
test3(h1); // 创建一个临时对象,接收 test3 函数的返回值,调用 1 次拷贝构造函数
Human h4 = test3(h1); // 仅调用 1 次拷贝构造函数,返回的值直接作为 h4 的拷贝构造函数的参数
test4(h1); // 因为返回的是引用类型,所以不会创建临时对象,不会调用拷贝构造函
Human men[] = { h1, h2, h3 }; //调用 3 次拷贝构造函数
return 0;
}
运行结果
浅拷贝 :只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块
深拷贝:是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象