c++构造函数的分类及调用(包含拷贝构造函数)。

分类:
按参数分为: 有参构造和无参构造
按类型分为:普通构造和拷贝构造

class person{
public:
//无参(默认)构造函数
person(){
cout<<"无参构造函数被调用"<<endl;
}
//有参构造函数
person(int a){
age=a;
cout<<"有参构造函数被调用"<<endl;
}
//拷贝构造函数
person(const person &p){//相当于拿一个对象去复制出来另一个对象,加上const是防止下面的函数体修改我原来的的模板p
age=p.age;
cout<<"拷贝构造函数被调用"<<endl;
}
//析构函数
~person(){
cout<<"析构函数被调用"<<endl;
}
int get_age(){
return age;
}
private:
int age;
}

调用方式分类:
1.括号法
2.显示调用法
3.隐式转换法

//调用无参构造函数
person p; //很简单,只需用类来声明一个对象即可,会自动调用无参构造
person p();这样写就不对,加上括号以后编译器会认为你定义了一个新的person类型的函数 
调用有参构造函数(不涉及拷贝构造参数)
//1.括号法
 person p1(10);//传入了一个值,编译器会去类中寻找与此匹配的构造函数
 person p2(p1);
 //2.显示法
 person p2=person(10);//调用有参构造函数
 person p3=person(p2);//调用拷贝构造函数
    //person(10)单独写就是相当于一个匿名对象,语句结束后会马上析构释放内存
  //3.隐式转换法
  person p4=10;//person p4=person(10); 调用有参
  person p5=p4;//person p5=person(p5);  调用拷贝构造函数
  //注意:不能利用拷贝构造函数初始化匿名对象
  person p5(p4)  编译器会认为这是一个对象声明,**上面已经有一个声明的p5**,所以这里就是重定义。
  
  person(p3); 编译器会认为这样就是 person p3;相当于一个对象的声明
  
2.拷贝构造函数的调用时机

1.使用一个以及创建完毕的对象来初始化一个新对象,就是按照模板再复制一个。

person p1;
person p2(p1);//这里要调用一次拷贝构造函数

在这里插入图片描述

2.值传递的方式给函数参数传值。(产生场景在函数传递数据之间)
这一条和临时对象基本一样,都是先复制出一个对象暂时存放,用完再清除。

class person{
	public:
		person(){
			cout<<"无参构造函数被调用"<<endl;
		}
		person(const person &p){
			cout<<"拷贝构造函数被调用"<<endl;
		}
};
void dowork(person p){}
int main()
{   person p;//调用无参构造函数来建立一个新对象,
	dowork(p);//调用拷贝构造函数,这里把实参p以值传递的方式传给上面的dowork函数,这时就得调用拷贝构造函数。
}

在这里插入图片描述

3.值传递的方式返回局部对象。
这里也和返回值的临时对象原理比较相似,只不过类比较大,不容易复制,所以给那段复制的代码起了个名字叫做复制构造函数而已,原理都一样。。

class person{
	public:
		person(){
			cout<<"调用无参构造函数"<<endl;
		}
		person(const person &p){
			cout<<"拷贝构造函数被调用"<<endl;
		}
};
//和2.中的程序不同的地方就是这里的返回值类型void变成了person类型
person dowork(person p){}   
int main()
{
	person p;//调用无参构造函数,这里要构建一个新对象
	dowork(p);//调用拷贝构造函数 
}

在这里插入图片描述

2.C++构造函数以及析构函数的若干面试问题

 Q1:构造函数能否重载,析构函数能否重载,为什么?
 A1:构造函数可以,析构函数不可以。
 
  Q2:析构函数为什么一般情况下要声明为虚函数?
  A2:虚函数是实现多态的基础,当我们通过基类的指针是析构子类对象时候,如果不定义成虚函数,那只调用基类的析构函数,子类的析构函数将不会被调用。如       果定义为虚函数,则子类父类的析构函数都会被调用。
  Q3:什么情况下必须定义拷贝构造函数?
  A3:当类的对象用于函数值传递时(值参数,返回类对象),拷贝构造函数会被调用。如果对象复制并非简单的值拷贝,那就必须定义拷贝构造函数。例如大的堆       栈数据拷贝。如果定义了拷贝构造函数,那也必须重载赋值操作符。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ad_m1n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值