c++类和对象之对象的初始化

1、构造函数概述

在c++程序中对象的初始化是一个不可缺少而十分重要的内容。为了对对象进行初始化,c++提供了构造函数来处理对象的初始化,构造函数是一种特殊的成员函数,与其他函数不同,构造函数时在建立对象时自动执行。
构造函数的作用:对象的初始化
构造函数的调用:由编译器自动调用
构造函数的调用时机:在创建对象时,系统会为该对象分配内存空间,并调用构造函数进行初始化
构造函数的要求:函数名与类名相同(以便编译器能够识别它,把它当作构造函数来处理),没有类型,不返回任何值。
注意:
1.如果用户没有自己定义构造函数,则c++系统会自动生成一个构造函数,只是这个构造函数的函数体是空的,也没有参数,不执行初始化操作。
2.构造函数可以重载
3.构造函数可以有默认参数
4.构造函数的重载与默认一般不同时使用,以免造成二义性问题。
5.如果用户自定义构造函数,系统不会指自动产生默认构造,但是会产生拷贝构造。
6.如果用户自定义拷贝构造,系统不会提供其他构造函数

2、构造函数的分类及调用

按参数分为
1.无参构造函数
2.有参构造函数
按类型分为
1.普通构造
2.拷贝构造
三种调用
1.括号发
2.显示发
3.隐士转换法

#include <iostream>
using namespace std;
class person
{
public:
	person()
	{
		cout << "person的无参构造调用" << endl;
	}
	person(int a)
	{
		age = a;
		cout << "person的有参构造调用" << endl;
	}
	person(const person &p)
	{
		age =p.age;
		cout << "person的拷贝构造调用" << endl;
	}
	~person()
	{
		cout << "person的析构调用" << endl;
	}
	int age;

};
void test01()
{
	//括号法
	person p1;//注意不要加(),否则会被认为函数声明
	person p2(100);
	person p3(p2);
	//显示法
	person p4;//注意不要加(),否则会被认为函数声明
	person p5=person(100);//如果将person(100)单独拿出来,就是匿名对象
	person p6=person(p5);
	//隐士转换法法
	person p7;//注意不要加(),否则会被认为函数声明
	person p8=100;//person p8=person(100);
	person p9=p8; //person p9 = person(p8);
}
int main()
{
	test01();
	return 0;
}

3、用初始化列表来初始化对象

person(int a):age(a)
	{
		age = a;
		cout << "person的有参构造调用" << endl;
	}

注意:用初始化列表进行初始化时,数据成员不能是数组,如果数据成员包含数组,则必须用函数体对数组进行初始化。

4、构造函数的重载

说明:
1.在建立对象时不必给出实参的构造函数称为默认构造函数。显然无参构造函数属于默认构造函数,一个类只能有一个默认构造函数,如果用户没有自定义构造函数,系统会自动产生一个默认构造函数,但是它的函数体是空的,不起初始化作用。
2.如果在建立对象时选用的时无参构造,则要注意其写法。

person p4;//注意不要加(),否则会被认为函数声明

3.尽管在一个类中可以有多个构造函数,但是对于每一个对象来说,只执行其中一个构造函数,并非每个构造函数都会被执行。

5、使用默认参数的构造函数

说明:
1.应该在构造函数声明的地方指定默认值,而不是只在定义构造函数时指定默认值。
2.在声明构造函数时,形参名称可以省略
3.如果全部参数都有默认值,则不用在写无参构造。
4.一般在使用默认参数的构造函数后,不应再使用函数重载,以免产生二义性问题。

6、对象的赋值和复制

一.对象的赋值
对象的赋值与普通变量的一样,赋值的一般形式
对象名1=对象名2;
注意这里的=本来只可以对单个变量的赋值,但是由于c++提供了运算符重载功能,使用=可以用于两个同类对象的赋值。
说明:
1.对象的赋值只对其中数据成员赋值,而不对数据对象赋值。
2.类的数据成员中不能包括动态分配的数据,否则在赋值时可能会出现严重后果。
二.对象的复制
复制的一般形式
类名 对象2(对象1);等价于
类名 对象2=对象1;
对象的复制是调用拷贝构造函数实现的。
总结:
对象赋值是对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行赋值。而对象的复制则是从无到有地建立一个新对象,并使它与一个已有对象完全相同(包括对象的结构和成员的值)

7、拷贝构造的调用时机

1.使用一个已经创建好的对象来初始化一个新对象
2.当函数的参数为类的对象

void fun(Person p){}
int main()
{
	Person p1(10);
	fun(p1);
	return 0;
}

3.函数的返回值时类对象

person fun()
{
	person p(10);
	rtunrn p;
}
int main()
{
	person p1;
	p1=fun();
	return 0;
}

8、深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝
深拷贝:在堆区申请空间,进行拷贝操作
浅拷贝带来的问题是堆区内存的重复释放。
解决方法是用深拷贝,在堆区重新开辟一段内存。

#include <iostream>
using namespace std;
class person
{
public:
	person(int a,int b)
	{
		age = a;
		height = new int(b);
		cout << "person的有参构造调用" << endl;
	}
	//深拷贝
	person(const person &p)
	{
		age =p.age;
		height = new int(*p.height);
		cout << "person的拷贝构造调用" << endl;
	}
	~person()
	{
		if (height != NULL)
		{
			delete height;
			height=NULL;
			
		}
		cout << "person的析构调用" << endl;
	}
	int age;
	int* height;

};
void test01()
{
	person p(18,180);
	cout << p.age<<"\t" << *p.height << endl;
	person p2(p);
	cout << p2.age<<"\t" << *p2.height << endl;

}
int main()
{
	test01();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@菜鸟一枚

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

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

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

打赏作者

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

抵扣说明:

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

余额充值