【C++基础】C++函数重载,缺省参数,命名空间问题

前几天开始学习C++语言,看到了函数重载的问题,就总结一下

什么是C++呢?(以下一段话出自搜狗百科),C++是一种面向对象的计算机程序设计语言,由美国AT&T贝尔实验室的本贾尼·斯特劳斯特卢普博士在20世纪80年代初期发明并实现(最初这种语言被称作“C with Classes”带类的C)。它是一种静态数据类型检查的、支持多重编程范式的通用程序设计语言。它支持过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。

C++是C语言的继承,进一步扩充和完善了C语言,成为一种面向对象的程序设计语言。

那么什么是函数重载呢?

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。

注意,在C语言中,函数名是不允许相同的,如果函数名相同就会出现函数重载问题

例如:

int func(int a, int b);
int func(int a, char c);
int func(char a, char b);

上面几个函数的名字是一样的,在C语言中,这样是不被允许的,但是在C++中,函数名是可以相同的,但是函数的参数也必须不相同。

在C++中,如果两个函数名字相同并且在相同的域中被声明,但是参数表不同,则它们就是重载函数

int ADD(int a, int b);
int ADD(float a, float b);

在C++中,这两个函数就是重载函数,重载函数的规则如下:

1.函数名称必须相同

2.参数列表必须不同

3.函数的返回类型可以相同也可以不相同。

注意,参数列表不同包括参数的个数不同、类型不同或顺序不同这三种情况。

那么为什么C++中会允许函数重载呢?

因为C++代码在编译时会根据参数列表对函数进行重命名

例如ADD(int a, int b)这个函数,会被重命名为ADD3_int_int,当函数调用时,编译器会根据传入的实参去逐个匹配,以选择对应的函数,如果匹配失败,编译器就会报错,这叫做重载决议(Overload Resolution)。

不同的编译器有不同的重命名方式,这例仅仅是举个栗子,并不一定是这种命名方式,如果你想具体知道编译器是如何实现的,可以在百度词条上看,或者找个编译器自己试试。

函数的缺省参数问题又是什么呢?

缺省参数,看字面意思,好像是函数可以在调用的时候缺省参数?

其实就是这样,函数在声明的时候制定初始值,在调用时就可以省略那个参数,但是函数的缺省参数还有许多规则:

1.函数能从后面一个参数开始省略,如果你想省略一个参数,那么你必须省略它后面的所有参数,即带缺省值的参数必须放在参数表的最后面

//正确
int Compare(int a, int b = 1);
//错误,一旦为函数的某个参数指定了缺省值,则必须为后续参数也定义缺省值
int RemoveNode1(LinkNode* head, int a = 1, int b);
//正确
int RemoveNode2(LinkNode* head, int a = 1, int b = 2, int c = 3);

2.缺省值必须是常量,所以缺省参数必须通过值参或常参传递

3.如果函数已经带有缺省参数的函数原型声明,则在该函数的定义中不允许出现缺省值。

4.调用函数时,如果略去一个参数传递,则略去后续所有参数传递

RemoveNode(head, 2);
RemoveNode(head, 2, 3);
//错误
RemoveNode(head, 2, , 4);

注意,要慎用函数的缺省参数,滥用的话会损害代码的结构和可读性,而且在函数重载时可能会出现二义性,例如:

void func(int a);
void func(int a, int b = 1);
//按照下面调用的话就会出现错误
func(100);

命名空间

在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。

为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。

namespace s1 
{
    int a = 1;
}
namespace s2 
{
    int a = 2;
}

就像上面的代码,在不同的命名空间有同一个名字的变量a,调用如下:

int c = s1::a;
int d = s2::a;

注意:这个符号(::) 是作用域解析运算符,用这个来访问命名空间内的成员

命名空间中的成员可以分为内部成员和外部成员,例如:

namespace s1 
{
    int a = 1;
    namespace s2 
    {
        int b = 2;
        void fun()
        {b++;}
    }
    //命名空间s2内的fun函数
    void fun(){a++;}
    //错误不能在命名空间中声明子命名空间
    namspace s2;
}
//命名空间s1的fun函数的外部定义
void s1::fun(){a++;}
//命名空间s2的fun函数的外部定义
void s1::s2::fun(){b++;}

不能直接使用“命名空间名::成员名 ……”定义方式,为命名空间添加新成员,而必须先在命名空间的定义中添加新成员的声明.

命名空间是开放的,可以多次声明和定义同一命名空间,可以用这样的方式来添加新成员

namespace s 
{
    int a;
    int arr[];
}
namspace a
{
    int c;
    char* str;
}
//现在命名空间a内有元素a,c,arr,str四个成员

为了省去每次调用Inner成员和标准库的函数和对象时,都要添加Outer::Inner::和sta::的麻烦,可以使用标准C++的using编译指令来简化对命名空间中的名称的使用。格式为:

using namespace 命名空间名[::命名空间名……];

在这条语句之后,就可以直接使用该命名空间中的标识符,而不必写前面的命名空间定位部分。因为using指令,使所指定的整个命名空间中的所有成员都直接可用。

例如:

#include<iostream>
//例如下面的代码
using namespace std;

简单的总结一下这三个东西,以后在学习C++中继续深入的了解和使用吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值