进击的C++(二)


仅作个人笔记学习交流使用

进击的C++(一)



一、函数参数

参数默认值

C++可以在函数声明时为参数提供一个默认值,当函数调用时没有提供参数的值,则使用默认值。
参数的默认值必须在函数声明中指定。
参数的默认值必须从右向左提供。
函数调用时使用了默认值,则后续参数必须使用默认值。

int square(int x = 0);
int square(int x)
{
	return x*x;
}
square();	//square(0) --> 0
square(2);	//square(2) --> 4

占位参数

占位参数只有参数类型声明,而没有参数名声明。
一般情况下,在函数体内部无法使用占位参数。
占位参数与默认参数结合使用,兼容C中可能的不规范写法(如 f(void) )。

void fun (int a,float)
{}

二、函数重载(overload)

重载——同一个标识符在不同的上下文中有不同的意义
函数重载——用同一个函数名定义不同的函数

int func(int x)
{
    return x;
}
int func(int a, int b)
{
    return a + b;
}
int func(const char* s)
{
    return strlen(s);
}

函数重载至少满足以下一个条件:

  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同
int add(int a, int b)  // int(int, int)
{
    return a + b;
}
int add(int a, int b, int c) // int(int, int, int)
{
    return a + b + c;
}

编译器函数重载的准则:

  • 将所有同命函数作为候选者
  • 尝试寻找可行的候选函数
    • 精确匹配实参
    • 通过默认参数能够匹配实参
    • 通过默认类型转换匹配实参
  • 匹配失败
    • 候选函数不唯一,出现二义性,编译失败
    • 无法匹配所有候选者,函数未定义,编译失败

注意

重载函数在本质上是相互独立的不同函数
重载函数的函数类型不同
函数重载时由函数名参数列表决定的
函数的返回值不能作为函数重载的依据
函数重载必然发生在同一个作用域中

函数重载与函数指针

将重载函数名赋值给函数指针时:

  • 根据重载规则选择与函数指针参数列表一致的候选者
  • 严格匹配候选者的函数类型与函数指针的函数类型
  • 无法直接通过函数名得到重载函数的入口地址
int func(int x)
{
    return x;
}
int func(int a, int b)
{
    return a + b;
}
int func(const char* s)
{
    return strlen(s);
}
typedef int(*PFUNC1)(int);			// int func(int x)
typedef int(*PFUNC2)(int,int);		// int func(int a,int b)
typedef int(*PFUNC3)(const char*);	// int func(const char* s)

三、C++调用C

C++编译器优先使用C++编译方式,能够兼容C的编译方式,使用extern强制让C++使用C编译方式。
__cplusplus 是C++编译器内置的标准宏定义,确保C代码以统一的C方式被编译为目标文件。

extern "C"
{
	//C code
}

#ifdef __cplusplus
extern "C" {
#endif

#include "Ccode.h"
//C code
#ifdef __cplusplus
}
#endif

注意

C++不能以C的方式编译重载函数
编译方式决定函数名被编译后的目标名:

  • C++编译方式将函数名参数列表编译成目标名
  • C编译方式只将函数名编译成目标名

四、C++动态内存分配

C++中通过new进行动态内存申请
C++中的动态内存申请是基于类型进行的
C++通过delete进行内存释放

Type* pointer = new Type;
delete pointer;

Type* pointerarr = new Type[N];
delete[] pointerarr;

newmalloc 对比

newmalloc
new是C++的关键字malloc是C库提供的函数
new 以具体类型为单位进行内存分配malloc以字节为单位进行内存分配
new 在申请单个类型变量时可进行初始化malloc不具备内存初始化特性

new 初始化

    int* pi = new int(1);		//()初始化
    // int* pa = new int[1];	//[]数组
    
    float* pf = new float(2.0f);
    char* pc = new char('c');

五、命名空间

C中只有一个全局作用域

  • 所有全局标识符共享同一个作用域
  • 标识符之间可能发生冲突

C++ 命名空间

  • 命名空间将全局作用域划分成不同的部分
  • 不同命名空间中的标识符可以同名而不冲突
  • 命名空间可以嵌套
  • 全局作用域也叫默认命名空间
int j = 0;
namespace External
{
    int i = 1;
    
    namespace Internal
    {
        struct P
        {
            int x;
            int y;
        };
    }
}

using namespace name;	//使用整个命名空间
using namespace External;

using name::variable;	//使用命名空间中的变量
using External::i;	
using External::Internal::P;	

using ::variable		//使用默认命名空间中的变量
using ::j;

六、类型转换

强制类型转换 xxx_cast (Expression)

static_cast

  • 用于基本类型间的转换
  • 不能用于基本类型指针间的转换
  • 用于有继承关系类对象之间的转换
  • 用于类指针之间的转换

void static_cast_demo()
{
    int i = 0x12345;
    char c = 'c';
   	c = static_cast<char>(i);	//c='E'
   	
    int* pi = &i;
    char* pc = &c;
    pc = static_cast<char*>(pi); //error: static_cast from 'int *' to 'char *' is not allowed
}

const_cast

  • 用于去除变量的只读属性
  • 强制转换的目标类型必须是指针引用

void const_cast_demo()
{
    const int& j = 1;
    int& k = const_cast<int&>(j);
    k = 5;
    printf("k = %d\n", k);
    printf("j = %d\n", j);
        
    const int x = 2;
    int& y = const_cast<int&>(x);
    int z = const_cast<int>(x); //error: const_cast to 'int', which is not a reference, pointer-to-object, or pointer-to-data-member
    y = 8;
    printf("x = %d\n", x);	//x=2
    printf("y = %d\n", y);	//y=8
    printf("&x = %p\n", &x);
    printf("&y = %p\n", &y);
}

reinterpret_cast

  • 用于指针类型间的转换
  • 用于整数指针类型间的转换

void reinterpret_cast_demo()
{
    int i = 0;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    
    pc = reinterpret_cast<char*>(pi);
    pi = reinterpret_cast<int*>(pc);
    pi = reinterpret_cast<int*>(i);
    c = reinterpret_cast<char>(i); //error: reinterpret_cast from 'int' to 'char' is not allowed
}

dynamic_cast

  • 用于有继承关系的类指针间的转换
  • 用于又交叉关系的类指针间的转换
  • 具有类型检查功能
  • 需要虚函数支持
void dynamic_cast_demo()
{
    int i = 0;
    int* pi = &i;
    char* pc = dynamic_cast<char*>(pi); //error: cannot dynamic_cast 'pi' (of type 'int*') to type 'char*' (target is not pointer or reference to class)
                                                                     
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值