C++入门--命名空间、函数默认参数、函数重载、内联函数

命名空间

C/C++中,变量、函数和类都是大量存在的。这些变量、函数和类都将存在于全局作用域中,可能会有很多冲突。使用命名空间的目的就是对标识符的名字进行本地化,以避免命名冲突和名字污染,于是namespace关键字出现了。

命名空间定义

定义命名空间:用namespace关键字,后面跟命名空间的名字,然后是一对 {},{}中即为命名空间中的成员。

//1.命名空间下可以放函数,变量和类,结构体以及命名空间
//2.命名空间必须定义在全局作用域下
//3.命名空间可以嵌套命名空间
namespace A {
	void func();
	int m_A = 20;
	struct Person {};
	class Animal {};
	namespace B {
		int m_A = 30;
	}
}

//4.命名空间是开放的,可以随时往原先的命名空间添加内容
namespace A {  //此命名空间会和上面的A命名空间合并
	int m_B = 100;
}

//5.无名、匿名命名空间
namespace {
	int m_C = 20;
	int m_D = 30;
}
//当写了无名命名空间,相当于写了 static int m_C=20,static m_D=30;
//只能在当前文件内使用

//6.命名空间可以起别名
namespace veryLongName {
	int m_A = 0;
}

void test04() {
	//起别名,和veryLongName是一样的
	namespace veryShortName = veryLongName;
	cout << veryLongName::m_A << endl;
	cout << veryShortName::m_A << endl;
}

命名空间的使用

namespace N
{
	int a = 10;
	int b = 20;
	int Add(int left, int right)
	{
	return left + right;
	}
	int Sub(int left, int right)
	{
		return left - right;
	}
}
int main()
{
	printf("%d\n", a); // 该语句编译出错,无法识别a。命名空间的内容只存在于命名空间中。
	return 0;
}

使用命名空间的三种方法

方法1:加命名空间名称及作用域限定符

int main(){
	cout<<N::a<<endl;	//注意是两个 :
	cout<<A::B::m_A<<endl;//当命名空间下还有命名空间,要这样访问。
}

方法2:使用using将命名空间中的成员引入

using N::b;//说明之后访问b都是这个成员变量。
int main(){
	cout<<b<<endl;
}

namespace D {
	int b=20;
}
int main()
{
	using D::b;
	int b = 30;
	cout << b << endl;
	system("pause");
}
//这种情况下将报错,b重定义,多次初始化。

方法3:使用using namespace命名空间名称引入

using namespace N;//这句代码相当于打开了 N这个房间。而没有使用房间里面的东西。
int main(){
	int a=10;
	cout<<N::a<<endl;
	cout<<a<<endl;	//不会报错。
	return 0;
}

函数默认参数

默认参数是声明或定义函数时为函数的参数指定一个默认值。再调用函数时,如果没有指定实参则采用该默认值,否则使用指定的默认值。

默认参数例子

void test(int a=10){
	cout<<a<<endl;
}
int main(){
	test();	//输出10
	test(20);//输出20
}

默认参数分类

//全默认参数

void test(int a=10,int b=20,int c=30){
	cout<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;
}
//半默认参数
void test(int a,int b=20,int c=30){
	cout<<"a:"<<a<<"b:"<<b<<endl;
}

注意:

1、默认参数必须从右往左一次给出,不能间隔着给出。

2、默认参数函数不能再声明和定义中同时出现,因为编译器不知道以哪个为标准。

3、参数必须是常量或全局变量。

4、C语言不支持默认参数。

函数重载

函数重载的具体可以参见我的另一篇博客:C/C++源文件到可执行文件、C++能重载C语言不能重载本质

内联函数

inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提高程序的运行效率。内联函数的引入是为了解决预处理宏的缺陷。

预处理宏的缺陷

在C++中我们可以使用:1、常量定义用const定义常量。2、函数定义换用内联函数定义。

缺陷一:导致代码可读性差、可维护性差、容易误读

//示例一:
#define ADD(x,y) x+y
void test(){
	int ret1 = ADD(10, 20) * 10; //希望的结果是300
	cout << "ret1:" << ret1 << endl; //210
}
//实例二:

#define compare(x,y) ((x)<(y)?(x):(y))

void test02(){
	int a=1,b=2;
	cout<<compare(++a,b)<<endl;
}

缺陷二:预定义宏函数没有作用域概念、无法作为一个类的成员函数,也就是说预定义宏没有办法表示类的范围

缺陷三:不方便调试宏(预编译阶段进行了替换)、没有类型检查

预处理宏的优点

预定义宏的优点:提高代码的复用性。提高性能。

内联函数的特性

1、inline是一种空间换时间的做法,省去调用函数的开销。所以代码很长或者有递归的时候不宜使用内联函数。

2、inline对于编译器只是一个建议,编译器不一定会接受这样的建议。编译器会自动优化,如果定义为inline的函体内有循环/递归等,编译器优化时会自动忽略内联。任何在类内部定义的函数自动成为内联函数。

3、inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。因为内联函数没有地址,所以不能对内联函数取地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值