C++笔记


前言

个人学习笔记


六、函数重载

       C语言不支持函数重载,而C++支持函数重载,其实质就是名字改编,当函数名字相同的时候,根据参数个数、顺序、类型去改编函数名字,在ubuntu下,可以通过-c选项(只编译不链接),通过nm命令查看生成的.o文件,可以看到改编后的函数名字,比如定义了int add()、int add(int x)、int add(int x, int y)、float add(float x, float y)、float add(int x, float y)等函数,那么只编译不链接之后,这些函数名字会改编成_Z3addv、_Z3addi、_Z3addii、_Z3addff,_Z3addif。
       C++兼容C语言的库函数时,不会按照C++的方式对C语言的库函数进行名字改编,就按照C语言的方式进行编译,这样才可以达到兼容的效果,否者像malloc、memset、free、printf等C语言库函数,C++可以自己重新实现一次,没必要调用,这也可以看出C语言是不支持名字改编的。
       如果想要在C++代码中按照C语言的方式进行编译,即不改编名字,可以通过extern “C” {},但这样又会带来一个问题,想要在C编译器中编译C++代码时,C编译器并不认识extern “C”,为了解决这个问题,通过C++的内置宏:ifdef __cplusplus就可以解决这个问题,在C++编译器上可以识别这个宏,把这个宏包裹的范围内的代码当成C代码进行编译,而在C编译器上,因为不能识别,就按默认方式,即C语言的方式进行编译,这就称为C与C++的混合编程。即函数重载->名字改编->extern “C”->C与C++的混合编程。
       这里需要注意一点,函数重载的实质是名字改编,而名字改编不涉及函数返回类型,所以仅仅返回类型不同不足以成为函数的重载。

#include <iostream>
using namespace std;
int add()
{
    int var = 1;
    return var + 1;
}
//C与C++的混合编程
#ifdef __cplusplus//C++的内置宏

extern "C"
{
#endif
    int add(int x)
    {
        return x;
    }
#ifdef __cplusplus//C++的内置宏
}//end of extern C
#endif
int add(int x, int y)
{
    return x + y;
}
int add(int x, int y, int z)
{
    return x + y + z;
}
float add(float x, float y)
{
    return x + y;
}
float add(int x, float y)
{
    return x + y;
}
int main()
{
    int a = 3, b = 4, c = 5;
    cout << "add(a, b) = " << add(a, b) << endl;
    cout << "add(a, b, c) = " << add(a, b, c) << endl;
    return 0;
}

七、默认参数

       默认参数的设置必须从右向左连续设置,因为在调用函数的时候,函数参数有入栈的过程,从右往左,为了对应这个过程,所以默认参数的设置也必须如此。通常将参数的默认值放在函数声明中。默认参数可以将一系列简单的函数重载合成为一个。

void func(); 
void func(int x);
void func(int x, int y); 
//上面三个函数可以合成下面这一个
void func(int x = 0, int y = 0);

void func(int x = 0, int y, int z = 0);//error,不可以这样设置,必须从右往左连续设置

       如果一组函数重载(可能带有默认参数)都允许相同实参个数的调用,将会引起调用的二义性,所以在函数重载时,要谨慎使用默认参数。

void func(int x, int y = 0); 
void func(int x = 0, int y = 0);
//调用func(3,4)时,上面的二个函数会产生二义性,编译器不知道该调用哪个函数

八、Bool类型

       任何非零值都将转换为true,而零值转换为false,简单来说就是:只要不是0,就是1。比如,bool b1 = -100, b2 = 100等,b1、b2的输出结果都是1。因为bool类型只需要表示2种状态,所以一个bool类型的数据在64位系统种占据的内存空间大小为1个字节。

九、内联函数

       宏定义发生的时机在预处理阶段,带参数的宏定义使用形式与函数类似,普通函数的调用会有入栈出栈的过程,而宏定义只是进行简单的字符串替换,所以运行效率更高,但如果宏定义有bug,那么直到运行的时候才会发现,而且宏定义不可以调试,所以不安全,而普通函数虽然运行效率不如宏定义但是较为安全。
       为了兼顾速度与安全,C++引入了内联函数,来降低程序的运行时间,编译器将使用函数的定义体来替代函数调用语句,其发生时机在编译阶段,内联函数即有宏定义的速度,又比函数的安全性。
       另外需要注意,对于inline函数而言,不能分成头文件与实现文件,即不能将声明与实现分开,内联函数一般实现简单的功能,不要加while/for等复杂语句,否则无法体现它的高效性。

#include <iostream>
using namespace std;

#define multiply(x, y) ((x) * (y))
inline int add(int x, int y)
{
    return x + y;
}

int main()
{
    int a = 3, b = 4, c = 5, d = 6;
    cout << "multiply(a, b)" << multiply(a, b) << endl;//带参数的宏定义使用形式与函数类似
    cout << "multiply(a + c, b + d)" << multiply(a + c, b + d) << endl;
	cout << endl;
    cout << "add(a, b)" << add(a, b) << endl;
    return 0;
}

十、异常安全

       C++ 异常处理涉及到三个关键字:try、throw、catch。

关键字含义
try激活try代码块中的特定异常,后面通常跟着一个或多个catch块。
throw当程序问题出现时,会抛出一个异常,通过throw关键字来完成的。
catch所有catch块匹配关键字throw抛出的异常(捕获异常)。
#include <iostream>
using namespace std;
void test()
{
    double x, y;
    cin >> x >> y;
    try{
        if(0 == y)//尽量把0写在前面
        {
            throw y;
        }
        else
        {
            cout << "(x / y)" << (x/y) << endl;
        }
    }
    catch(double dx)
    {
        cout << "catch(double dx)" << endl;
    }
}
int main()
{
    test();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值