c++中类和对象

c++构造函数

1、在创建对象时,系统会自动调用构造函数(不能手动调用)

2、构造函数能重载和设置默认参数值,析构函数则不能

浅拷贝和深拷贝

1、

2、

 移动构造
explicit关键字

1、explicit关键字的作用就是防止类构造函数的隐式自动转换.

2、explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了.(但是, 也有一个例外, 就是当除了第一个参数以外的其他参数都有默认值的时候, explicit关键字依然有效, 此时, 当调用构造函数时只传入一个参数, 等效于只有一个参数的类构造函数

new和malloc两者的区别

1、属性

new/delete:这两个是C++中的关键字,若要使用,需要编译器支持;

malloc/free:这两个是库函数,若要使用则需要引入相应的头文件才可以正常使用。

2、使用上

malloc:申请空间需要显式填入申请内存的大小;

new:无需显式填入申请的内存大小,new会根据new的类型分配内存。

3、内存位置

new:此操作符分配的内存空间是在自由存储区;

malloc:申请的内存是在堆空间。

C/C++的内存通常分为:堆、栈、自由存储区、全局/静态存储区、常量存储区。可能除了自由存储区,其他的内存分布大家应该都比较熟悉。

 是C语言和操作系统的术语,堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,调用free()归还内存。那什么是自由存储区呢?

自由存储区 是C++中动态分配和释放对象的一个概念,通过new分配的内存区域可以称为自由存储区,通过delete释放归还内存。自由存储区可以是堆、全局/静态存储区等,具体是在哪个区,主要还是要看new的实现以及C++编译器默认new申请的内存是在哪里。但是基本上,很多C++编译器默认使用堆来实现自由存储,运算符new和delete内部默认是使用malloc和free的方式来被实现,说它在堆上也对,说它在自由存储区上也正确。因为在C++中new和delete符号是可以重载的,我们可以重新实现new的实现代码,可以让其分配的内存位置在静态存储区等。而malloc和free是C里的库函数,无法对其进行重载。

4、返回类型的区别

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。所以在C++程序中使用new会比malloc安全可靠。

5、分配失败情况的区别

malloc分配内存失败时返回NULL,我们可以通过判断返回值可以得知是否分配成功;

new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL,分配失败时如果不捕捉异常,那么程序就会异常退出,我们可以通过异常捕捉的方式获取该异常

6、定义对象系统调度过程的区别

使用new操作符来分配对象内存时会经历三个步骤:

调用operator new 函数(对于数组是operator new[])分配一块足够的内存空间(通常底层默认使用malloc实现,除非程序员重载new符号)以便存储特定类型的对象;

编译器运行相应的构造函数以构造对象,并为其传入初值。

对象构造完成后,返回一个指向该对象的指针。

使用delete操作符来释放对象内存时会经历两个步骤:

调用对象的析构函数。

编译器调用operator delete(或operator delete[])函数释放内存空间(通常底层默认使用free实现,除非程序员重载delete符号)。

7、扩张内存大小的区别

malloc:使用malloc分配内存后,发现内存不够用,那我们可以通过realloc函数来扩张内存大小,realloc会先判断当前申请的内存后面是否还有足够的内存空间进行扩张,如果有足够的空间,那么就会往后面继续申请空间,并返回原来的地址指针;否则realloc会在另外有足够大小的内存申请一块空间,并将当前内存空间里的内容拷贝到新的内存空间里,最后返回新的地址指针。

new:new没有扩张内存的机制。

c++中左值与右值,移动构造函数

1、左值:存储在内存中、有明确存储地址(可寻址)的数据

 2、C++中的左值也可以当作右值使用

3、“&”表示的引用又称为左值引用

4、C++11 标准新引入了另一种引用方式,称为右值引用,用 "&&" 表示、

右值引用

1、声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化

2、右值引用可以修改右值

int &&a=10;
a=12;
cout<<a<<endl

3、非常量左值引用可以引用的值的类型只有非常量左值,常量左值引用非常量左值、常量左值及右值

	int num = 10;
	int& a = num;	//编译成功,非常量左值引用支持引用非常量左值
	const int num2 = 100;
	int& b = num2;	//编译失败,非常量左值引用不支持引用常量左值
	int& c = 10;	//编译失败,非常量左值引用不支持引用右值
 
	const int& d = num;		//编译成功,常量左值引用支持引用非常量左值
	const int& e = num2;	//编译成功,常量左值引用支持引用常量左值
	const int& f = 100;		//编译成功,常量左值引用支持引用右值

4、右值引用不支持引用左值;非常量右值引用可以引用的值的类型只有非常量右值,常量右值引用非常量右值、常量右值

	int num = 10;
	const int num2 = 100;
	int&& a = num;	//编译失败,非常量右值引用不支持引用非常量左值
	int&& b = num2;	//编译失败,非常量右值引用不支持引用常量左值
	int&& c =10;	//编译成功,非常量右值引用支持引用非常量右值
	const int&& d = num;	//编译失败,常量右值引用不支持引用非常量左值
	const int&& e = num2;	//编译失败,常量右值引用不支持引用常量左值
	const int&& f = 100;	//编译成功,常量右值引用支持引用右值

5、move()函数将左值强制转换到右值

	int num = 10;
	int&& a = std::move(num);  //编译成功
	cout << a << endl;   //输出结果为10;

6、移动构造函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值