-
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++增强了很多功能,当然也有许多需要注意的地 方。由于本教程面向初学者,因此到此为止,不再深入下去。
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式