公司网站换服务器怎么做论坛推广网站
拷贝构造函数
注意:访问权限是public
拷贝构造函数:类名(const 类名& 对象名){} 可以有多个参数 。 没有常引用就是普通构造函数
如果不写,编译器自己会给一个(作用仅仅是赋值,默认拷贝构造函数一直都在)
#include<iostream>
using namespace std;class person {
public:int age;string name;person(int age,string name):age(age),name(name) {cout << "含参构造函数" << endl; }person(const person& p) {age = p.age;name = p.name;cout << "拷贝构造函数" << endl;}void show() {cout << "姓名:" << name << " | 年龄:" << age << endl;}~person() { cout << "析构函数" << endl; }
};int main()
{person p1(100,"xxx");person p2(p1); //p2=p1 效果一样p1.show();p2.show();return 0;
}
函数值传递过程中会调用拷贝构造函数,因为函数形参本身就是一份赋值(值传递)
//伪代码
//注意,传引用和指针都不会激活拷贝构造
void f(person p) {p.show();
}person p;
f(p);void g(person* p){p->show();
}person *p=new person(x); //有参就调用有参构造,否则默认构造
g(p);
delete(p); //调用析构
p=NULL;
函数以值的方式返回对象时,可能会调用拷贝构造函数(vs会,linux不会,g++做了优化)
//伪代码
person f(person p)
{person pf(p);return pf;
}
person p(1, "sdf");
person p2 = f(p);
p2.show();//引用1
person& g()
{person p; //每读到这句就一个默认构造return p; //g函数结束就析构p
}
person p;
g()=p;
g().show(); //乱码//引用2
person& g(person& p)
{return p;
}
person p1;
person p2;
g(p1)=p2;
g(p1)->show(); //p2的值
注意析构函数调用时机:作用域结束(mian函数结束)
如果类重载拷贝构造函数,却没有定义默认构造函数,编译器会提供一个
class person {int age;person(int a):age(a){cout << "有参构造" << endl;}//person(const person& p) { //注释默认构造// cout << "默认拷贝构造" << endl;// age = p.age;//}person(const person& p, int i){age = i;cout << "重载拷贝构造" << endl;}void show() {cout << "age:" << age << endl;}
};int main()
{person p(10);p.show();person p2(p); //编译器又提供一个 p2.show(); return 0;
}
深浅拷贝
对空指针解引用是非法的
#include<iostream>
using namespace std;class person {
public:int a;int* p;person(){a = 0; p = nullptr;cout << "person构造函数" << endl;}person(const person& per){a = per.a;//p = per.p; //浅拷贝//深拷贝p = new int; //分配内存*p = *per.p; //拷贝数据cout << "person拷贝构造函数" << endl;}~person() //浅拷贝问题:p1和p2指向同一个空间,p1销毁后,到p2销毁就会崩溃{delete p; p = nullptr;cout << "person析构函数" << endl;}void show(){cout << a << " " << p << " " << *p << endl;}
};int main()
{person p1;p1.a = 10; p1.p = new int(2);p1.show();person p2(p1);p2.show();return 0;
}