C++的namespace,defalut funtion,reference,inline

namespace(命名空间)

C++为了解决C语言之间命名的问题,创造了命名空间,防止命名的冲突。
部分展开
标准命名空间里面封装了这些函数,需要展开才能使用这些函数。

#include <iostream>
using std::cout;
using std::endl;//展开这两个函数,后续就不应该和这两个函数重名
int main()
{
    cout<<1<<endl;
    return 0;
}

我们因为展开了这个命名空间里面的cout和endl才可以使用,否则就不能使用。
全展开

#include <iostream>
//命名空间


//1.全展开//注意展开部分在整个文件就都展开了,后续和重名的话,依然会报错
using namespace std;
int main()
{
    cout<<1<<endl;
    return 0;
}

如这里,就是对std标准命名空间的展开,使得我们可以使用标准命名空间里的函数,这种展开方式称之为全展开,在整个文件里面,都不应该再出现重名,否则就会出现错误。

嵌套使用

#include <iostream>
//3.嵌套,直接使用
namespace FUH{
    namespace FUH_CS{
        int a = 1;
    }
    int a(int a,int b)//we can define the function in the namespace
    {
        return a+b;
    }
}
using namespace std;
int main()
{
    cout<<FUH::a(1,FUH::FUH_CS::a)<<endl;//out "2"
    return 0;
}

如上,命名空间可以嵌套使用。

缺省函数

缺省函数指有些函数可以给初始值,同时给了初始值的参数可以不给值

  • 全缺省函数,定义/声明全部给了缺省值,调用时可以不给参数。
    • 一般来说,声明和定义时可以分开的,如果函数的声明与定义分开,只需要在一处给出缺省值即可。推荐给在定义处,因为一般的编辑器都是支持转到定义,这样方便查看
  • 注意,传输默认参数需要具有顺序,不默认的参数需要在默认的前面(左侧先定义),默认参数可以传参
  • 无参数同名函数和全缺省函数,不能在同一作用域里同时存在,在下面函数重载有提及
#include <iostream>
using namespace std;

//缺省函数 default funtion
void func(int a =10)//函数参数会又默认值,当不给予传输参数,形式变量为默认值
{
    cout<<a<<endl;   
}

//半缺省--必须从右往左缺省
void func_2(int a,char b = 'b',char c = 'a')//注意,传输默认参数需要具有顺序,不默认的参数需要在默认的前面(左侧先定义),默认参数可以传参
//因为在传参的时候,从左往右传输参数。
{
    cout<<b<<endl;
    cout<<a<<endl;
    cout<<c<<endl;
}



// 缺省函数一般声明给了初始化,定义不给,缺省值只能是常量或者全局变量
//引用,例如栈的初始化(这里给整形数组代表),
void stack_initial(int *arr,int n)
{
    arr = (int*)malloc(sizeof(int)*4);
    if(arr = NULL)
    {
        perror("malloc fail");
    }
    return ;
}
void stack_initial(int *arr,int n = 5);

//全缺省函数,调用时可以不给参数。
int add(int a = 10,int b = 0)
{
	return a+b;
}

函数重载(function overload)

指c++里面可以给出因参数类型不同参数个数不同参数顺序不同之间的同名函数且在同一作用域构成函数重载。

#include <iostream>
using namespace std;
//同一作用域,函数同名,但是函数参数个数,类型,类型顺序不同,都可以以重载(overload)来实现不同功能

int Add(int a,int b=10)
{
    return a+b;
}
double Add(double a,double b)
{
    return a+b;
}

如果像下面这样写一个重载的函数,会导致调用存在歧义,编译器也报错

int Add()
{
    return 1;
}
int Add(int a = 10)//这是一个全缺省函数
{
	return a;
}


int main()
{
    cout<<Add(1)<<endl;
    cout<<Add(2.2,3.4)<<endl;
    return 0;
}

原因就是因为二义性,编译器不知道要调用谁作为参数。

引用

已经存在的变量起一个别名,引用定义的这个变量,所指向的依旧是同一块空间

  • 引用定义时必须初始化
  • 引用不能权限越界,参考例子三
  • 函数在返回引用类型时,引用类型必须不被销毁
    例如静态,全局,堆上malloc的空间,否则会出现野指针的问题。

例子一:

int main()
{

    int a = 0;
    int& b = a;//b就是对于a的引用,注意b不能不初始化,引用必须指向一块空间。
    //b就和a指向同一块内存,b改变值,a也改变值
    cout<<&b<<endl;
    cout<<&a<<endl;
    return 0;
}

例子二:
函数在使用引用传参的时候,使用引用传递参数,就可以改变原参数,
原因是这个形式参数(引用)指向的也是原实参数的内存

void change(int& b)
{
    b += 10;
    return ;
}
int main()
{
    int a = 0;
    change(a);
    cout<<a<<endl;//输出a+10之后的值,说明a的值已经被改变
    return 0;
}

函数在返回引用类型时,引用类型必须不被销毁
例如静态,全局,堆上malloc的空间,否则会出现野指针的问题。

int& A()
{
    int* a = (int*)malloc(sizeof(int)*1);
    *a = 10;
    return *a;
}
int& B()
{
    int a = 11;
    return a;
}

int main()
{
    cout<<A()<<endl;//输出10
    // cout<<B()<<endl;//这里实际就应该报错,程序崩溃,因为访问了一块未申请的内存。

    return 0 ;
}

引用的权限只能不得超越原变量的权限
例子三

int main()
{
    int a = 0;
    int& b = a;//true

    const int c = 0;
    //int& d = c;//这里就会报错
    const int &d = c ;//这样才是正确的引用

    int e = 10;
    //double& f = e;//这里一样报错
    const double& f = e;//改正后正常
    //原因是隐式类型转换,和c类似,这里不是e值直接给f,是把e提升成一个double的临时值,拿给f引用
    //因为这块内存是在常量区的,所以遵循权限一致,加const
    cout<<&e<<endl;
    cout<<&f<<endl;
    cout<<f<<endl;
    cout<<sizeof(f)<<endl;
    return 0;
}

其实,引用在底层就是用指针的方式来实现的,也就能理解上述的原因了
指针引用区别区别:有多级指针,无多级引用
必须给引用初始化,指针不需要
类型上引用是设定时的类型,但是指针就是指针类型(有单独的指针类型)

内联函数

cpp用inline 函数代替了宏函数
内联函数由于类似宏一样,直接展开,是不生成函数地址的
所以不要去分开声明和定义(也就是源文件定义,头文件声明的操作,因为不生成函数地址,也不是说去调用的问题)
直接在头文件定义然后使用即可
一般来说,编译器都只支持较小的函数且非递归函数做内联函数,否则就视作正常函数
这样一来,直接再头文件定义也不会显得很臃肿。

内联函数与宏的比较
内联函数更加安全,宏函数使用风险更大
内联函数相比较于宏的开销更大,代码复用性也不如宏

inline int a()
{
    cout<<"a"<<endl;
}
int main()
{
    a();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值