C++ 简介
C几乎是C++的一个子集,所以C语言支持的语法在C++基本都支持并需要使用。既然名字叫做 C plus plus(C++), 所以它在C的基础上又有了很多新的特性。
C 语言是面向过程的
而 C++ 是面向对象的
面向对象的三大特性就是
封装
继承
多态
C++ 中比 C 语言多了一个 class 类型
任何事物都可以写成一个类 class
class Student {
public:
void print() {
cout << m_name << endl;
cout << m_name << endl;
}
private:
char* m_name;
size_t m_age;
}
例如上面的这个学生类 , 有姓名 , 年龄 , 两个成员变量 , 还有一个 print 成员函数
其实和 C 语言的结构体很像 , 就是多了一个 成员函数
其中的 public 和 private 叫做访问限定符 , 用来规定访问权限
重载
C 语言中的函数 , 不可以同名 , 但是在 C++ 中是可以存在同名函数的
只要同名的函数满足一下条件即可
在同一作用域类
参数列表不同(个数不同 / 类型不同)
返回值可同可不同 // 为什么 ?
编译过程一般分为:
预处理 — 编译 — 汇编 — 链接
预处理:展开头文件,宏替换,去掉注释,条件编译等工作。生成.i文件
编译:语法检查,生成汇编代码。 生成.s文件
汇编:将汇编代码转成机器码 。 生成.o文件
链接:将之前生成的文件链接到一起,生成可执行文件 , .out文件
如果有多个.cpp文件,在链接之前各文件都是独立向下进行的,各文件之间没有交集。
所以C++支持重载的原因 , 就在链接这个阶段上,C语言在链接的时候根据函数名找要调用的函数
C++而是根据函数名和参数类型来寻找要调用的函数
例如下面的代码 , 我写了两个 print 函数
#include <iostream>
#include <string>
using namespace std;
void print()
{
cout << "Jim" << endl;
cout << 21 << endl;
}
void print(string t_name, size_t t_age)
{
cout << t_name << endl;
cout << t_age << endl;
}
int main()
{
print();
print("tom", 20);
return 0;
}
编译完成之后 , 我们用命令 objdump -d a.out > log.txt 反汇编并将结果重定向到log.txt文件中
我们发现在汇编代码中 , 两个 print 函数变成了下面的名字
08048960 <_Z5printv>:
// void print()
080489d0 <_Z5printSsj>:
// void print(string t_name, size_t t_age)
可以猜想 , _Z5 代表返回值类型 , print 函数名 , v / Ssj 代表参数列表 , 即 返回值类型+函数名+参数列表
所以C++可以根据函数名和参数类型来寻找要调用的函数 , 也就支持了重载
上面说函数重载的条件 , 返回值可同可不同 // 为什么 ?
这是为了在解析操作符或函数调用时,独立于上下文(不依赖于上下文)
float sqrt(float);
double sqrt(double);
void f(double da, float fla)
{
float fl = sqrt(da); //调用sqrt(double)
double d = sqrt(da); //调用sqrt(double)
fl = sqrt(fla); //调用sqrt(float)
d = sqrt(fla); //调用sqrt(float)
}
如果考虑了返回值的类型 , 那么上面的函数调用过程就不能独立于上下文了
缺省参数
也就是可以在函数的形参列表中赋一个初值
全缺省参数
int Add1 (int a = 0, int b = 0)
{
return a + b;
}
半缺省参数
int Add2 (int a, int b = 0)
{
return a + b;
}
void Test ()
{
Add1(); // 0
Add1(1); // 1
Add1(1, 1); // 2
Add2(2); // 2
Add2(2, 2); // 4
}
默认参数只能从右往左设置
因为函数调用时是从左往右匹配参数的
int add(int a = 0, int b);
这样就没什么意义了 , 因为调用函数 add() , 总会把默认参数覆盖
命名空间
命名空间域是随标准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++库里的成员
其中 :: 叫 作用域解析符
本文介绍了C++相较于C语言的新特性,包括面向对象编程的基本概念如封装、继承和多态,新增的class类型及其使用方式,函数重载的概念及其实现原理,缺省参数的用法,以及命名空间的作用。
1048

被折叠的 条评论
为什么被折叠?



