gcc 编译
GCC
gcc 编译选项
说明
-E
预处理,但不进行编译
-S
编译指定的源文件,但不进行汇编
-c
编译、汇编生成目标代码,但不进行链接
-o file1 file2 或 file2 -o file1
将文件 file2 编译成文件 file1
-I directory
指定头文件的搜索目录
-L
编译的时候指定搜索库的路径
-l
编译的时候指定使用的库
-g
在编译的时候,生成调试信息,该程序可以被调试器调试
-D
在程序编译的时候,指定一个宏
-w
不生成任何警告信息
-Wall
生成所有警告信息
-On
n 为 0~3,优化选项,3 级别最高
-fPIC/fpic
生成与位置无关的代码
-shared
生成共享目标文件,通常用在建立共享库时
-std
指定 c 版本,如 -std=c99
预处理
12gcc -E main.cpp # 不会生成 .i 文件gcc -E main.cpp -o main.i
编译
12gcc -S main.cpp # 生成 main.sgcc -S main ...
C++ IO库
IO 类
头文件
类型
iostream
istream 和 wistream 从流读取数据,ostream 和 wostream
向流写入数据,iostream 和 wiostream 读写流
fstream
ifstream 和 wifstream 从流读取数据,ofstream 和 wofstream
向流写入数据,fstream 和 wfstream 读写流
sstream
istringstream 和 wistringstream 从 string 读取数据,ostringstream 和
wostringstream 向 string 写入数据,stringstream 和 wstringstream 读写
string
条件状态
条件状态
说明
strm::iostate
strm 是一种 IO 类,提供了表达流状态的完整功能
strm::badbit
用于指出流已崩溃
strm::failbit
用于指出一个 IO 操作失败
strm::eofbit
用于指出流到达了文件结束
strm::goo ...
C++ 面向对象
面向对象 OOP
面向对象程序设计三大特性:封装,继承和多态
继承
继承方式
public 继承
protected 继承
private 继承
基类 public 成员变成
派生类的公有成员
派生类的保护成员
派生类的私有成员
基类 protected 成员变成
派生类的保护成员
派生类的保护成员
派生类的私有成员
基类 private 成员变成
只能通过基类接口访问
只能通过基类接口访问
只能通过基类接口访问
结构体默认 public 继承,类默认 private
继承
使用 final 关键字,可以防止类被继承
1class NoDerived final {}; // NoDerived 不能作为基类
使用 using 关键字时,可以重新定义成员的访问权限为基类中的任何访问级别(public、protected
或 private),这样可以根据需要调整派生类中成员的可访问性
12345678910111213class Base { public: std::size_t size() const { return n; } ...
C++ 对象移动
右值和右值引用
左值可以位于赋值语句的左边,但右值不行,比如一个常量,只能出现在右边
通过 &&
获得右值引用,右值引用只能绑定到有个即将销毁的对象,因此可以将一个右值引用的资源
移动 到另一个对象中
123456int i = 42;int &r = i; // 正确,r 引用 i,左值引用int &&rr = i; // 错误,不能将一个右值引用绑定到一个左值上int &r2 = i * 42; // 错误,i * 42 是一个右值const int &r3 = i * 42; // 正确,可以将一个 const 引用绑定到右值int &&rr2 = i * 42; // 正确,将 rr2 绑定到乘法结果上
标准库 move
上面提到过不能将右值引用绑定到左值上,但可以显式地将左值转换为对应的右值引用类型,还可以通过
move 的新标准库函数来获得绑定到左值上的右值引用
12345#include <utility>int &&rr1 = 42; // 正确,字面常量是右值int & ...
C++ 重载运算
运算符重载
C++ 使用 operator 关键字来重载运算符
1234返回值类型 operator运算符(参数){ ...}
重载后,操作符至少有一个是用户定义的类型
不能违反运算符原本的句型规则,% x 是不行的
不能创建新的运算符
不能修改运算符优先级
大多数运算符都能通过成员或非成员函数进行重载,但
=, (), [], -> 只能通过成员函数进行重载
以 = 为例
12345678910111213141516171819202122232425262728293031323334#include <iostream>using namespace std;class Tmp{private: int n;public: Tmp(); Tmp(int m); int Get() const;};Tmp::Tmp() { n = 0; cout << "111" << endl;}Tmp::Tmp(int m) { n = m; cout << "222" << ...
C++ 类
成员函数
类声明时通常将短小的成员函数作为内联函数,以此来减少函数调用所带来的开销
123456789101112131415Class Stock{private: std::string company; long shares; double share_val; double total_val; void set_tot(total_val = shares * share_val); // 内联函数public: void acquire(const std::string &co, long n, double pr); void buy(long num, double price); void sell(long num, double price); void update(double price); void show();}
也可以在类声明外定义使其成为内联函数,只需显示声明
inline
12345678910class Stock{private: void set_tot();}i ...
C++ 编译模式
程序结构
将程序分为 3 部分
头文件,包含结构声明和使用这些结构的函数的原型
函数原型
使用 #define 或 const 定义的符号常量
结构声明
类声明
模板声明
内联函数
源代码文件:包含与结构有关的函数的代码
源代码文件:包含调用与结构相关的代码
函数定义除了内联函数,不要放在头文件中,因为如果多个源文件包含该头文件,就会导致函数的多次定义
编译多个源文件时,预处理将包含的文件与源代码文件合并,然后编译器创建每个源代码文件的目标代码文件,最后链接程序将目标代码文件、库代码和启动代码合并,生成可执行文件