函数重载是什么
函数重载,及函数名相同的2个函数被称为重载函数,函数重载的出现有效的解决了函数命名问题,使得代码的可读性有了很大的提高。
构成重载的条件
不是2个任意的函数都可以构成重载函数,函数重载需要一些条件。
1.函数名相同,参数类型不同(被const修饰的参数不会造成二义性),参数数量不同的只要不构成二义性的函数可以构成重载,返回值类型无法构成重载。
2.二义性是什么:二义性就是在调用函数时,存在2个或以上均满足调用条件或无最佳匹配函数的函数可被调用,则就有了二义性,如一个无参的Print函数和一个全缺省的Print函数存在二义性,隐式类型转换均可调用多个函数,无最佳匹配函数。
底层如何区分,匹配重载函数
Linux中,符号表中对于函数的描述不仅只描述了函数的名字,还描述了函数的参数,以及参数的个数,所以编译器才能区分同名函数。
在同名函数匹配时,须经过几个过程
1.先选出函数名相同,并且被声明过的函数。
2.随后选出参数个数相同,参数类型相同或可以隐式转换的函数。
3.选出最佳匹配函数调用。
内存管理操作符
C++内存管理操作符有两个new,delete,new用来在堆区开辟空间,delete用来释放堆区空间。
操作符与C库函数的区别
1.对于C++操作符来说,可以对自定义类型进行内存开辟/销毁,但是C的库函数则不可以,原因是因为C库函数不能完成对自定义类型构造函数/析构函数的调用。
2.对于C库函数来说,若开辟/释放空间失败,则会返回NULL,这不符合面向对象的思维,而new,delete操作符若开辟/释放空间失败,则会抛出异常,符合面向对象思维。
内存管理操作符底层原理
new,delete操作符其实是对malloc,free函数进行了分装,new,delete其实是将malloc,free分装为了operator new,operator delete函数。
void *operator new(size_t size, const std::nothrow_t&)
_THROW0()
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
{
// buy more memory or return null pointer
_TRY_BEGIN
if (_callnewh(size) == 0) break;
_CATCH(std:bad_alloc) return (0);
_CATCH_END
}
return (p);
}
void operator delete(void *pUserData)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
同时开辟/释放连续空间的操作符为new[],delete[],这两个操作符其实是封装了new,delete。
内存管理操作符的注意事项
new,delete,new[],delete[],要配套使用。
new[]会在实际内存前开辟一个整形大小,用来记录开辟类型的个数,用来确定调用构造/析构函数的次数delete[]在释放内存时会先向后移动一个整形大小,随后在释放内存,而delete却不会,所以混用会导致释放部分空间,导致报错。