-
C++教程之用别名指定名字空间
用别名指定名字空间
名字空间可以一层层嵌套,指定时也得一层层地指定,这样很不方便,一般用 别名代替就方便多了。
#include using namespace std; namespace na { namespace nb { namespace nc { int sum(int
{
a,
int
b)
return
} } } }
a + b;
namespace int
{
A = na::nb::nc;
main ( )
cout << na::nb::nc::sum(5, 11) << endl; cout << A::sum(6, 12) << endl;
return
}
0;
四、没有名字的名字空间
名字空间的名字也可以省略,称之为“无名名字空间”,无名名字空间经常被使 用,其作用是“内部可以引用,而外部不能引用”。
#include using namespace
std;
namespace na { namespace { //无名名字空间 int sum(int a, int b)
{
return
} }
a + b;
int
{
calc(int x,
int
y)
return
} }
sum(x, y);
//内部可以调用无名名字空间的变量或函数
int
{
main ( )
//cout << na::sum(5, 11) << endl; 以外部不能调用
cout << na::calc(6, 12) << endl;
//因为缺少里面的名字,所
return
}
0;
03 章 缺省参数和函数重载
一、参数的缺省值
在 C++中参数可以设置缺省值,设置了缺省值之后,这个参数在调用时可以省 略。注意:设置缺省值的参数只能是最后的几个参数。也就是说某一个参数一旦设 置了缺省值,其后而的参数也必须设置缺省值。例如:f()函数有 3 个参数,如果只 设置第 2 个有缺省值,这就错了。因为调用时只输入 2 个参数时,系统不知道究竟 是第 2 个参数还是第 3 个参数。
#include using namespace std;
int sum(int x=0, int y=100, int z=0) { return x+y+z; } //int sum(int x, int y=100, int z=0) { …… } //这是正确的 //int sum(int x, int y, int z=0) { …… } //这也是正确的 //int plus(int x, int y=100, int z) { …… } //这是错误的 int
{ cout << sum() << endl; cout << sum(6) << endl; cout << sum(6, 10) << endl; cout << sum(6, 10, 20) << endl; main ( )
return
}
0;
二、函数的重载
函数的重载在 C++中具有重要作用,重载(overload)不要和后面要学的覆盖 (override)混淆起来。重载是指相同的函数名,但参数的类型或个数中只要有所不同, 便进行再定义,编译之后重载的函数都具有不同的地址,也就是说虽然函数名相同, 实际上是不同的函数,在调用时,编译系统会根据不同之处自动区别是调用哪一个 函数。对于普通函数和后面要学的类的成员函数都适用。 覆盖只对类的构造函数或成员函数适用,是子类继承父类是才使用的非常有用 的功能。重载可以针对运算符,而覆盖不行。上一节中缺省值的设置,实际上在编 译时等价于重载,被生成了 4 个不同的函数。 早期的 C++版本,在定义重载函数时要加上关键字 overload,现在不用了。在 使用重载函数时,如果有类型的自动转换时要特别注意,初学者往往出错在这儿。
#include using namespace std; float fun(float x); double fun(double x); int
{ float f = 132.64; main ( )
double
d = 132.64;
cout << fun(f) << endl; cout << fun(d) << endl;
//cout << fun(5) << endl; 也可转换为 double return
} 0;
//编译错, 参数 5 可以转换为 float,
float
{
fun(float x)
return
}
x / 2.0 ;
double
{
fun(double x)
return
}
x / 3.0;
三、设计时的重载错误
上面的例子中,设计时并没有问题,调用时类型自动转换时发生了二义性。下 面列举的重载函数是设计时就出了问题,二个函数本身就具有重复的意义。
#include using namespace std; int int int
{ fun(int a, fun(int a,
int int
b); &b);
main ( )
int
x=1, y=2;
cout << fun(x, y) << endl;
//这句编译时出错
return
}
0;
int
{
fun(int a,
int
b);
return
a + b;
}
int
{
fun(int a,
int&
b);
return
}
a - b;
上面例子用到了 int&,这叫“引用”,关于什么是“引用”参见下一章。
四、重载函数的地址
本节利用函数指针的方法来取函数的地址,有关函数指针请参考“C 语言教程” 的章节。本节虽没有特别高深内容,但初学者还是跳过为好。
#include using namespace std; void void int
{ space(int count); space(int count,
char
ch);
main ( )
//有一个整型参数的函数指针 void (*fp1)(int); //有一个整型参数、一个字符型参数的函数指针 void (*fp2)(int, char);
fp1 = space; fp2 = space;
//取 space(int)函数的地址 //取 space(int, char)函数的地址 //输出 20 个空格 //输出 20 个等号
fp1(20);
cout << "|" << endl; fp2(20, '=');
cout << "|" << endl;
return
}
0;
//输出 count 个空格字符
void
{
space(int count)
for
}
( ; count; count--) cout << ' ';
//输出 count 个 ch 字符 void space(int count, char
{
ch)
for
( ; count; count--) cout << ch;
04 章 引用
一、独立引用
“引用(reference)”与指针象似但不是指针。 引用主要有 3 种用法: ①单独使用(一 般称为“独立引用”),②作参数使用,③作返回值使用。从功能上来说,引用型变量 又可以看着被引用变量的“别名”, 2 个变量只是名称不同, 这 变量的地址是同一个(共 用体中的元素也是一样)。使用“引用”的好处主要是可以“逆向引用”。 常量也可以被引用,例如:“const int &ref = 10;”,这也是正确的,但这样定义 无任何意义。定义独立引用时需要注意以下规则: 1. 引用型变量在定义时必须初始化。 2. 被引用的对象必须已经分配了空间,即不能为空,或空指针。 3. 被引用的对象不能为地址,即指针变量、数组变量等不能被引用。
#include using namespace std; int
{ main( )
int int
a ; &b = a;
//b 和 a 实际上是同一变量 //b 赋值为 100,也就是 a 赋值为 100
b = 100;
cout << a << endl;
//a 的地址和 b 的地址应该是完全一样
cout << &a << endl; cout << &b << endl;
//▼下面代码有错,注释后才能运行▼int x[] = {12,15,20} ; int &y = x; //错误:数组、指针不能被引用 int int
x1; &y1;
//错误:引用时必须初始化
y1 = x1;
//▲上面代码有错,注释后才能运行▲return
} 0;
二、函数的参数引用 函数的参数引用
许多教程在讲解参数引用时都喜欢选择交换两参数内容的 swap(int &x, int &y) 函数作例子,这的确很容易说明清楚,但并不能说这种用法优于指针作参数。
#include using namespace std; //|右边为指针作参数的代 码,仅作比较用。 void swap(int &x, int &y); int
{ main ( )
int int
i = 12; j = 25; j=" << j << endl;
cout << "i=" << i << "
swap(i, j); cout << "i=" << i << " j=" << j << endl;
return
}
0;
void swap(int &x, int &y)
{
int
t;
//|void swap(int *x, int *y); //| //| //| //| //| //| //| //|swap(&i, &j); //| //| //| //| //| //|void swap(int *x, int *y) //|{ //| int t; //|
t = x; x = y; y = t; }
//| //| //| //|}
t = *x; *x = *y; *y = *x;
三、对象引用作参数
初学者可以先跳过这一节,待学完“类”之后再来看。
#include using namespace std; class
myclass {
int who;
public:
myclass(int n) { who = n; cout << "构造函数调用" << who << endl; } ~myclass() { cout << "析构函数调用" << who << endl; }
int
} };
id() {
return
who;
void
}
f1(myclass o) {
//普通变量方式传递参数
cout << "外部函数调用" << o.id() << endl;
void
}
f2(myclass *o) {
//指针方式传递参数
cout << "外部函数调用" << o->id() << endl;
void
}
f3(myclass &o) {
//引用方式传递参数
cout << "外部函数调用" << o.id() << endl;
int
{
main ( )
myclass x1(1); f1(x1); cout << "" << endl;
myclass x2(2); f2(&x2); cout << "" << endl;
myclass x3(3); f3(x3); cout << "" << endl;
return
}
0;
从上面例子可以看出,用普通变量方式传递参数时,函数首先将参数复制一个 副本,在函数体内使用的是副本。这个副本和参数自身不是同一个地址。而指针方 式和引用方式并不产生副本,函数体内用的真是参数自身。需要注意的是,产生副 本时调用了类的缺省“拷贝构造函数”,这个“拷贝构造函数”并不调用构造函数就产 生了一个副本,有关详细内容参见后面章节。
四、作为函数返回值的引用类型
这一节仍然较深,建议初学者跳过。讲解这一节内容之前,先看下面的程序, 这个程序有没有毛病?
#include using namespace std; int int int
{ f() = 100; cout << x << endl; &f(); x;
main ( )
return
}
0;
int
{
&f()
return
}
x;
许多人都认为第 9 句错了,少数人认为第 4 句可能有问题。事实上,这个程序 完全正确。上面这个函数的返回值是引用类型,通过函数结果的设置反过来去改变 “源头”数据,这种“逆向引用”为 C++增强了很多功能,当然也有许多需要注意的地 方。由于本教程面向初学者,因此到此为止,不再深入下去。
名字空间可以一层层嵌套,指定时也得一层层地指定,这样很不方便,一般用 别名代替就方便多了。
#include using namespace std; namespace na { namespace nb { namespace nc { int sum(int
{
a,
int
b)
return
} } } }
a + b;
namespace int
{
A = na::nb::nc;
main ( )
cout << na::nb::nc::sum(5, 11) << endl; cout << A::sum(6, 12) << endl;
return
}
0;
四、没有名字的名字空间
名字空间的名字也可以省略,称之为“无名名字空间”,无名名字空间经常被使 用,其作用是“内部可以引用,而外部不能引用”。
#include using namespace
std;
namespace na { namespace { //无名名字空间 int sum(int a, int b)
{
return
} }
a + b;
int
{
calc(int x,
int
y)
return
} }
sum(x, y);
//内部可以调用无名名字空间的变量或函数
int
{
main ( )
//cout << na::sum(5, 11) << endl; 以外部不能调用
cout << na::calc(6, 12) << endl;
//因为缺少里面的名字,所
return
}
0;
03 章 缺省参数和函数重载
一、参数的缺省值
在 C++中参数可以设置缺省值,设置了缺省值之后,这个参数在调用时可以省 略。注意:设置缺省值的参数只能是最后的几个参数。也就是说某一个参数一旦设 置了缺省值,其后而的参数也必须设置缺省值。例如:f()函数有 3 个参数,如果只 设置第 2 个有缺省值,这就错了。因为调用时只输入 2 个参数时,系统不知道究竟 是第 2 个参数还是第 3 个参数。
#include using namespace std;
int sum(int x=0, int y=100, int z=0) { return x+y+z; } //int sum(int x, int y=100, int z=0) { …… } //这是正确的 //int sum(int x, int y, int z=0) { …… } //这也是正确的 //int plus(int x, int y=100, int z) { …… } //这是错误的 int
{ cout << sum() << endl; cout << sum(6) << endl; cout << sum(6, 10) << endl; cout << sum(6, 10, 20) << endl; main ( )
return
}
0;
二、函数的重载
函数的重载在 C++中具有重要作用,重载(overload)不要和后面要学的覆盖 (override)混淆起来。重载是指相同的函数名,但参数的类型或个数中只要有所不同, 便进行再定义,编译之后重载的函数都具有不同的地址,也就是说虽然函数名相同, 实际上是不同的函数,在调用时,编译系统会根据不同之处自动区别是调用哪一个 函数。对于普通函数和后面要学的类的成员函数都适用。 覆盖只对类的构造函数或成员函数适用,是子类继承父类是才使用的非常有用 的功能。重载可以针对运算符,而覆盖不行。上一节中缺省值的设置,实际上在编 译时等价于重载,被生成了 4 个不同的函数。 早期的 C++版本,在定义重载函数时要加上关键字 overload,现在不用了。在 使用重载函数时,如果有类型的自动转换时要特别注意,初学者往往出错在这儿。
#include using namespace std; float fun(float x); double fun(double x); int
{ float f = 132.64; main ( )
double
d = 132.64;
cout << fun(f) << endl; cout << fun(d) << endl;
//cout << fun(5) << endl; 也可转换为 double return
} 0;
//编译错, 参数 5 可以转换为 float,
float
{
fun(float x)
return
}
x / 2.0 ;
double
{
fun(double x)
return
}
x / 3.0;
三、设计时的重载错误
上面的例子中,设计时并没有问题,调用时类型自动转换时发生了二义性。下 面列举的重载函数是设计时就出了问题,二个函数本身就具有重复的意义。
#include using namespace std; int int int
{ fun(int a, fun(int a,
int int
b); &b);
main ( )
int
x=1, y=2;
cout << fun(x, y) << endl;
//这句编译时出错
return
}
0;
int
{
fun(int a,
int
b);
return
a + b;
}
int
{
fun(int a,
int&
b);
return
}
a - b;
上面例子用到了 int&,这叫“引用”,关于什么是“引用”参见下一章。
四、重载函数的地址
本节利用函数指针的方法来取函数的地址,有关函数指针请参考“C 语言教程” 的章节。本节虽没有特别高深内容,但初学者还是跳过为好。
#include using namespace std; void void int
{ space(int count); space(int count,
char
ch);
main ( )
//有一个整型参数的函数指针 void (*fp1)(int); //有一个整型参数、一个字符型参数的函数指针 void (*fp2)(int, char);
fp1 = space; fp2 = space;
//取 space(int)函数的地址 //取 space(int, char)函数的地址 //输出 20 个空格 //输出 20 个等号
fp1(20);
cout << "|" << endl; fp2(20, '=');
cout << "|" << endl;
return
}
0;
//输出 count 个空格字符
void
{
space(int count)
for
}
( ; count; count--) cout << ' ';
//输出 count 个 ch 字符 void space(int count, char
{
ch)
for
( ; count; count--) cout << ch;
04 章 引用
一、独立引用
“引用(reference)”与指针象似但不是指针。 引用主要有 3 种用法: ①单独使用(一 般称为“独立引用”),②作参数使用,③作返回值使用。从功能上来说,引用型变量 又可以看着被引用变量的“别名”, 2 个变量只是名称不同, 这 变量的地址是同一个(共 用体中的元素也是一样)。使用“引用”的好处主要是可以“逆向引用”。 常量也可以被引用,例如:“const int &ref = 10;”,这也是正确的,但这样定义 无任何意义。定义独立引用时需要注意以下规则: 1. 引用型变量在定义时必须初始化。 2. 被引用的对象必须已经分配了空间,即不能为空,或空指针。 3. 被引用的对象不能为地址,即指针变量、数组变量等不能被引用。
#include using namespace std; int
{ main( )
int int
a ; &b = a;
//b 和 a 实际上是同一变量 //b 赋值为 100,也就是 a 赋值为 100
b = 100;
cout << a << endl;
//a 的地址和 b 的地址应该是完全一样
cout << &a << endl; cout << &b << endl;
//▼下面代码有错,注释后才能运行▼int x[] = {12,15,20} ; int &y = x; //错误:数组、指针不能被引用 int int
x1; &y1;
//错误:引用时必须初始化
y1 = x1;
//▲上面代码有错,注释后才能运行▲return
} 0;
二、函数的参数引用 函数的参数引用
许多教程在讲解参数引用时都喜欢选择交换两参数内容的 swap(int &x, int &y) 函数作例子,这的确很容易说明清楚,但并不能说这种用法优于指针作参数。
#include using namespace std; //|右边为指针作参数的代 码,仅作比较用。 void swap(int &x, int &y); int
{ main ( )
int int
i = 12; j = 25; j=" << j << endl;
cout << "i=" << i << "
swap(i, j); cout << "i=" << i << " j=" << j << endl;
return
}
0;
void swap(int &x, int &y)
{
int
t;
//|void swap(int *x, int *y); //| //| //| //| //| //| //| //|swap(&i, &j); //| //| //| //| //| //|void swap(int *x, int *y) //|{ //| int t; //|
t = x; x = y; y = t; }
//| //| //| //|}
t = *x; *x = *y; *y = *x;
三、对象引用作参数
初学者可以先跳过这一节,待学完“类”之后再来看。
#include using namespace std; class
myclass {
int who;
public:
myclass(int n) { who = n; cout << "构造函数调用" << who << endl; } ~myclass() { cout << "析构函数调用" << who << endl; }
int
} };
id() {
return
who;
void
}
f1(myclass o) {
//普通变量方式传递参数
cout << "外部函数调用" << o.id() << endl;
void
}
f2(myclass *o) {
//指针方式传递参数
cout << "外部函数调用" << o->id() << endl;
void
}
f3(myclass &o) {
//引用方式传递参数
cout << "外部函数调用" << o.id() << endl;
int
{
main ( )
myclass x1(1); f1(x1); cout << "" << endl;
myclass x2(2); f2(&x2); cout << "" << endl;
myclass x3(3); f3(x3); cout << "" << endl;
return
}
0;
从上面例子可以看出,用普通变量方式传递参数时,函数首先将参数复制一个 副本,在函数体内使用的是副本。这个副本和参数自身不是同一个地址。而指针方 式和引用方式并不产生副本,函数体内用的真是参数自身。需要注意的是,产生副 本时调用了类的缺省“拷贝构造函数”,这个“拷贝构造函数”并不调用构造函数就产 生了一个副本,有关详细内容参见后面章节。
四、作为函数返回值的引用类型
这一节仍然较深,建议初学者跳过。讲解这一节内容之前,先看下面的程序, 这个程序有没有毛病?
#include using namespace std; int int int
{ f() = 100; cout << x << endl; &f(); x;
main ( )
return
}
0;
int
{
&f()
return
}
x;
许多人都认为第 9 句错了,少数人认为第 4 句可能有问题。事实上,这个程序 完全正确。上面这个函数的返回值是引用类型,通过函数结果的设置反过来去改变 “源头”数据,这种“逆向引用”为 C++增强了很多功能,当然也有许多需要注意的地 方。由于本教程面向初学者,因此到此为止,不再深入下去。
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
JavaScript判断两个数组相等的四类方法
js如何操作video标签
React实战--利用甘特图和看板,强化Paas平
【记录】正则替换的偏方
前端下载 Blob 类型整理
抽象语法树AST必知必会
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程