1. 命名空间
名字空间域是随标准 C++ 而引入的。它相当于一个更加灵活的文件域(全局域),可以用花括号把文件的一部分括起来,并以关键字 namespace 开头给它起一个名字:
namespace name1
{
int a = 0;
}
namespace name2
{
int a = 1;
}
name1::a = 3;
name2::a = 4;
名字空间域解决了全局命名冲突的问题。
标准 C++ 库中的所有组件都是在一个被称为 std 的名字空间中声明和定义的。在采用标准 C++ 的平台上使用标准 C++ 库中的组件,只要写一个 using 指示符:using namespace std; 就可以直接使用标准 C++ 库中的所有成员。或者 std::成员 的方式也可以使用 C++ 库里的成员。其中::是作用域解析符。
namespace std // std是C++标准库的名字空间
{
// 标准库成员
}
举例:
#include <iostream>
using namespace std;
int main()
{
std::cout << "hello world" << std::endl;
system("pause");
return 0;
}
运行结果如下:
2. C++基本的输入输出流
cout 是标准输出流对象,<< 是输出操作符;
cin 是标准输入流对象,>>是输入操作符;
endl 是换行操作符;
它们都属于C++标准库,所以都在 std 的名字空间里面。
举例:
#include <iostream>
using namespace std;
int main()
{
int i1 = 1;
double d1 = 5.55;
cout << "c++ type:" << "int->" << i1 << " double->" << d1 << endl;
cout << "please input int and double:";
cin >> i1 >> d1;
cout << "c++ type:" << "int->" << i1 << " double->" << d1 << endl;
system("pause");
}
运行结果如下:
3. 重载(C++为什么支持重载?)
函数重载:在同一作用域类,一组函数的函数名相同,参数列表不同(个数不同/类型不同),返回值可相同可不同。
对于 C++ 语言作为一种欲与 C 兼容的语言,C++ 语言保留了一部分过程式语言和特点,foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C++ 语言就是靠这种机制来实现函数重载的。
为什么C++支持函数重载,而C语言不支持呢?
从代码的编译到运行,在 VC6.0 或 VS 这种编译器下,它是系统直接完成了翻译与链接,直接生成了运行结果。
编译器内部完成了翻译部分:
1)预处理
(1)头文件展开
(2)宏的替换
(3)去注释
(4)条件编译
2)编译过程:将高级语言转为汇编语言
3)汇编过程:汇编语言转为二进制程序
链接部分:将所引用的数据链接进来
比如一个函数的声明如下:void function(int x,int y);
在 C 语言中,编译器在编译后在库中的名字为 _function;在 C++ 中,编译器在编译后在库中的名字为_function_int_int。
还有一个函数的声明如下:void function(float x,float y);
在 C 语言中,编译器在编译后在库中的名字为_function;在 C++ 中,编译器在编译后在库中的名字为_function_float_float。
在链接时,都是找名字进行链接的,就比如以上两个函数,在 C 语言中两个的名字一样,就会在链接中报错。C++ 中它们的名字不一样,就不会报错。
我们可以在 Linux 下使用 objdump 查看目标文件中的函数名字的修饰来认识函数重载。
4. C++缺省参数
// 全缺省参数
int Add1(int a = 0, int b = 0)
{
return a + b;
}
// 半缺省参数
int Add2(int a, int b = 0)
{
return a + b;
}
void Test()
{
Add1();
Add1(1);
Add1(1, 1);
Add2(2);
Add2(2, 2);
}
半缺省参数:当有多个参数时,缺省在右边且是连续的。
5. 指针和引用
1) 概念:引用不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名。
2)格式:类型 &引用变量名 = 已定义过的变量名;
特点:(1)一个变量可取多个别名
(2)引用必须初始化
(3)引用只能在初始化的时候引用一次,不能改变再引用其他的变量。
3)做参数:
(1)值传递:如果形参为非引用的传值方式,则生成局部临时变量接收实参的值。
void Swap (int left, int right)
{
int temp = left;
left = right ;
right = temp ;
}
(2)引用传递:如果形参为引用类型,则形参是实参的别名。
void Swap (int& left, int& right)
{
int temp = left;
right = left ;
left = temp ;
}
(3)指针传递:void Swap (int* pLeft, int* pRight)
{
int temp = *pLeft;
*pLeft = *pRight;
*pRight = temp;
}
void TestReference2 ()
{
int a = 1;
int b = 2;
cout<<"a:" <<a<< endl;
cout<<"b:" <<b<< endl;
Swap (a , b);
cout<<"a:" <<a<< endl;
cout<<"b:" <<b<< endl;
}
当不希望函数内改变参数 x 的值时,尽量使用常引用传参。
4)做返回值:int& Add (int d1, int d2) //传引用做返回值
// int Add ( int d1 , int d2) //传值做返回值
{
int ret = d1 + d2;
return ret ;
}
void ()
{
int a = 3, b = 4;
int c = Add( a, b );
cout<<"c:" <<c<< endl;
}
不要返回一个临时变量的引用。
如果返回对象出了当前函数的作用域依旧存在,最好使用引用返回,因为这样更高效。
5)引用和指针的区别和联系
(1)引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变。
(2)引用必须指向有效的变量;指针可以为空。
(3)sizeof 指针对象和引用对象的意义不一样。sizeof 引用得到的是所指向的变量的大小;而 sizeof 指针是对象地址的大小。
(4)指针和引用自增(++)和自减(--)意义不一样。
(5)相对而言,引用比指针更安全。
指针比引用更灵活,但是也更危险。使用指针时一定要注意检查指针是否为空。指针所指的地址释放以后最好置 0,否则可能存在野指针问题。