1.浮点数的表示
分为三部分,31符号位 ,30~23 ,22~0
2.const
理解英文从右向左读 (* 读成point to)
char * const cp;cp is a const pointer to char
const char * p ; p is a pointer to const char;
char const * p; p is a pointer to char (that is const )const
3.动态内存
ZZ: http://gs5689.blogbus.com/logs/36655475.html
在GNU系统中,malloc或realloc返回的内存块地址都是8的倍数(如果是64位系统,则为16的倍数)。如果你需要更大的粒度,请使用memalign或valloc。这些函数在头文件“stdlib.h”中声明。
在GNU库中,可以使用函数free释放memalign和valloc返回的内存块。但无法在BSD系统中使用,而且BSD系统中并未提供释放这样的内存块的途径。
函数:void * memalign (size_t boundary, size_t size)
函数memalign将分配一个由size指定大小,地址是boundary的倍数的内存块。参数boundary必须是2的幂!函数memalign可以分配较大的内存块,并且可以为返回的地址指定粒度。
函数:void * valloc (size_t size)
使用函数valloc与使用函数memalign类似,函数valloc的内部实现里,使用页的大小作为对齐长度,使用memalign来分配内存。它的实现如下所示:
void *
valloc (size_t size)
{
return memalign (getpagesize (), size);
}
3.面向对象,类
Class Vector {
private:
int * element;
int size;
public :
int getSize(){
return size;
};
}
拷贝构造函数:
Vector(Vector v1)
通过使用另一个同类型的对象来初始化新创建的对象,如果类中没有的话,编译器会自行定义一个。
重新申请一块空间,将V1的成员变量值依次赋值给新创建的函数,注意带有指针时要自定义该函数,对指针成员变量进行深拷贝工作。
举例,调用拷贝构造函数的三种情况:
Type B =A;
Type B(A);
Type foo(){return A}; Type B = foo();
赋值构造函数:
重载的赋值运算符
Vector &::oprator=(const Vector @a){
}
类运算符重载:+ 、- 、=等
Type B;
B = A;
move 构造函数:
Vector(Vector &&a)
浅拷贝之后,将a重设。
友元函数
定义在类的外部
不是成员函数
定义友元函数后可以访问的成员变量:
静态成员:
static 定义变量,将变量放到全局区,相当于全局
声明类的成员为类时,无论创建多少个对象,静态成员都只有一个副本,在所有对象中是共享的。
初始化要在类的外部。
静态成员函数:
不属于类的任何一个成员函数
可以在对象不存在的情况下也能被调用,ClassName::Static_function
只能访问静态成员数据、其他静态成员函数和类的外部函数
不能使用this指针。
枚举和枚举类:
enum enumTyoe{W,M,N}
本质为整形N
枚举类型是安全的
Union
只用一个类型,取其最大的成员空间
Union Value{
char *i;
int B;
}
Struct in C++
默认为public
多态:
一个事物的多种形态,C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
继承:
Public,private,protected继承
public 继承,状态不变。
private 继承基类,全部变成private,用于对基类的实现
protect 继承,基类的public变成了派生类的protect
虚函数:用virtual定义
有一个virtual table的指针,指向虚拟表,在运行时去找虚拟表中的函数。
编译时期绑定,早绑定,一般是基类函数中不带有virtual
运行时期绑定,晚绑定,一般是基类函数中带有virtual
gdb 命令
info vtb bl 查看虚拟表
info symbol 0x5555555551e8 查看上条命令的详细信息
继承函数调用 B::A
初始化:B -> A
析构的时候,析构函数为虚函数:A->B
类的内存布局:
纯接口类 :没有实现
实现类:继承接口类,并实现接口定义的函数
casting 强制转换运算符
const_cast<type>(expr) 修改类型的const属性
dynamic_cast<type>(expr) 在运行时执行转换,验证转换的有效性,type必须是类的指针、类的引用或void*,type和expr类型相同
static_cast<type>(expr) 执行非动态转换,没有运行时类检查来保证转换的安全性
reinterpret_cast<type>(expr) 把某种指针改为其他类型的指针
unique_ptr:智能指针 ,一个包含着指针的类,防止内存泄露。
namespace:定义了一个范围,不要放在头文件里
类的不可改性
const 成员函数
const 成员变量
class 为final,不能被继承
模板:
模板是泛型编程的基础,可以用模板来定义函数或类。
模板函数
template<class type>
ret_type func_name(parameter list){
...
}
类模板
template<class T1,class T2>
class A{
T1 data1;
T2 data2;
}
声明
编译展开,将用到的类型全部展开为函数,AST(后期详细理解),可递归
编译时间极大增加
全特化:
template<>
class A<int,double>{
int data1;
double data2
}
template<>
void<int>(){int d;}
偏特化
函数模板不可以偏特化。
template<class T2>
class A<int ,T2>{
...
}
元编程
一个接受类型并返回类型的函数
template<typename T>
class Vector{
public:
using val_type = T;
};
template<typename C>
using Element_type = typename C:val_type;
template<typename Container>
void algo<Container& C>{
Vector<Element_type<Container>> vec;
}
//Element_type<Container> => Container:val_type
//Vector<int> => vec = int
//
constexpr
编译器在编译时期可以确定的值
constexpr x = 1.4 * squera(5);//编译时期,x = 35
constexpr squera(x){
return x*x;
}
模板的高级特性:
template<typename T,int N>
struct Buffer{
using value_type = T;
constexpr int size(){
return N;
}
T[N];
}
Buffer<char,1024> gloab; //编译期申请了1024个char空间
void fct(){
Buffer<int,10> buf;//在栈上申请10个integer大小的空间
}
Variadic Templates
可以接受任何长度的输入
递归展开
template<typname T>
void g(T x){
cout << x << " ";
}
void f(){};
template<typename T,typename... Tail>
void f( T head, Tail... tail){
g(head);
f(tail);
}
int main(){
f(1,3.3,"Hello")
}
STL (Standart Template Library)
容器
std::vector
doubling :双倍分配内存(不同STD标准不同),第一次申请一个,第二次申请一个,第三次申请两个,第四次不申请,第五次申请四个 。。。
Elem 指向空间的起始
Space 指向空余空间的起始
Last 指向空间的末尾
API
int size(); //元素的个数,Space - Elem
int capacity() ; //剩余可用空间 Last - Space
void reserve(int newsz); //increase capacity() to newsz
void push_back(const T& t); //copy t into vector
void push_back(T&& t); // move t into vector
智能指针<memory>,
为了解决内存泄露问题,当该对象被销毁时,会在其析构函数中删除关联的原始指针。
这是一个模板类,但是禁用了拷贝构造函数。
unique_ptr(move语义)独有的,一个资源只有一个指针指向它,当没有指针指向时,自动delete。
shared_ptr(copy语义)共享的,有个count计算多少指针指向,当count=0时,释放。
weak_ptr 监测shared_ptr的状态。
#include <memory>
class ResourceType{
public:
void foo(){};
...
}
void dowork(const weak_ptr<ResourceType> &wptr){
if(wptr.expired()) return;//如果过期
auto sharedResource = wptr.lock();
}
int main(){
unique_ptr<ResourceType> r1 {std::make_unique<ResourceType>()}
auto r2{std::make_unique<ResourceType>()}
r1->foo();
//unique_ptr<ResourceType> r3 = r2;//错误
unique_ptr<ResourceType> r3 = std::move(r2);//把r2转移到r3了,r2指针不指向原来的值了
shared_ptr<ResourceType> r1 {std::make_shared<ResourceType>()};
auto r2{std::make_shared<ResourceType>()};
r1->foo();
shared_ptr<ResourceType> r3 = r2;//r2指向的资源count+1
shared_ptr<ResourceType> rr1 {std::make_shared<ResourceType>()};
weak_ptr<ResourceType> weakResource(rr1);//rr1的count不会增加
dowork(weakResource);//正常执行
rr1.reset();//清空释放资源
dowork(weakResource);//失效,返回
}
Lambda
匿名函数
capture list(外部变量访问方式说明符),表示{}中用到的变量权限。包含= (只读) 和&(可修改)
-> 可以省略,让编译器自行推导
例:
[]表示{}内的外部变量不可见
[= ,&x,&y] 表示外部变量性,y的值可以被修改,其余外部变量可见但是不可修改
[&,x,y]表示除x,y以外的外部变量,值都可以被修改
[capture list] (parameter_list) -> return type declaration{...}
int main(){
std::string name ="This is lambda";
auto square=[=](const int& value){
std::out<< name << std::endl;
return value*value;
}
std::out<< square(10) << std::endl;
}
Functor
#include<vector>
template<typename T>
void print(const std::vector<T>& v){
for(T n:v){
std::cout << n << " ";
}
std:cout << std::endl;
}
class IncreasingNumberGenerator{
public:
int operator(){} noexcept{
return number++;
}
prvate:
int number(0);
}
int main(){
const size_t AMOUNT_OF_NUMBERS(10);
std::vector<int> numbers(AMOUNT_OF_NUMBERS);
std::generate(std::begin(numbers),std::end(numbers),IncreasingNumberGenerator());
print(numbers);
return 0;
}
Iterator_traits
Type Predicates
在编译时间检查类型<type_traits>
进阶:
设计模式、C++模板、c++模板元编程、BooSt库