编译.cpp .h
过程分为四个过程:编译(编译预处理、编译、优化.s
),汇编.o
,链接。
静态链接
动态链接
栈区:
正常函数体内{}"
定义的都是。
连续内存。
堆区:
new
出来的。
类似链表的分段内存。
全局/静态存区:
static
和全局变量extern
.
常量区:
常量。
代码区:
编译后的二进制文件。
全局变量:
放在.cpp
文件里面的,不再{}
内的变量,同样的名称多文件共享。
多个cpp
文件共用或者{}
内使用需要extern
修饰声明。
静态全局变量:
static
修饰,具有文件作用域,多个文件同样的名称是不同的变量。
局部变量:
{}
里面定义的。
静态局部变量:
static
修饰的{}
函数中的变量,具有函数作用域,只初始化一次。
对齐存取快,不报异常好迁移。
有些设备不支持非对齐的存取,不能保证原子操作。
new
出来的内存,由指针进行操作,后来没delete
指针指向别的了,之前的那块内存地址就找不到了,没法删除啥的。
智能指针,自动释放内存,防止内存泄露。
shared_ptr
多个指针共享一块内存,通过引用计数自动释放。
unique_ptr
一个指针独占一块内存,不能拷贝赋值。可以移动构造和移动赋值构造。
weak_ptr
指向 shared_ptr 指向的对象,能够解决由shared_ptr带来的循环引用问题。
https://www.iteye.com/blog/kooyee-340846解释:
<>
先去系统目录中找头文件,如果没有在到当前目录下找。所以像STL
标准的头文件 stdio.h、stdlib.h
等用这个方法。
而""
首先在当前目录下寻找,如果找不到,再到系统目录中寻找。 这个用于include自定义的头文件,让系统优先使用当前目录中定义的。
auto
auto var = val1 + val2; //定义+初始化为左边的值
decltype
decltype(val1 + val2) var1 = 0; //定义+初始化为其他值
[capture list/*捕获的局部变量列表*/] (parameter list/*形参*/) -> return type/*返回变量类型*/
{
/*具体函数实现*/
function body;
};
for (declaration /*列表中的一个元素*/: expression/*列表、数组*/){
statement
}
这玩意不和python的for差不多吗,多了个declaration的变量类型常用auto
。
delete 函数:= delete
表示该函数不能被调用。default 函数:= default
表示编译器生成默认的函数,例如:生成默认的构造函数。#include
using namespace std;
class A
{
public:
A() = default; // 表示使用默认的构造函数
~A() = default; // 表示使用默认的析构函数
A(const A &) = delete; // 表示类的对象禁止拷贝构造
A &operator=(const A &) = delete; // 表示类的对象禁止拷贝赋值
};
int main()
{
A ex1;
A ex2 = ex1; // error: use of deleted function 'A::A(const A&)'
A ex3;
ex3 = ex1; // error: use of deleted function 'A& A::operator=(const A&)'
return 0;
}
bool
类型,用int
代替virtual
虚函数实现。重载:
就是函数的重载,和面向对象没关系
隐藏:
子类的同名函数会隐藏父类的同名函数,如果需要调用父类函数需要.Base::fun()
重写(覆盖):虚函数,纯虚函数(子类一定要重写)
父类的函数有virtual
修饰,函数名、参数列表、返回值类型需要一致。
主要应用:父类指针指向new
子类对象,实现父类指针调用子类的函数。
这玩意太多了还是直接看别人写的吧
explicit
:避免编译器进行隐式类型转换static
:
virtual
函数。只能访问static
成员。因为静态成员函数没有 this 指针。const
:修饰常量不能更改,只能初始化时候赋值。mutable
修饰使得const
的某些成员一直保持是可以改变的。#define
:在编译预处理阶段进行文本替换typedef
:定义类型的别名inline
:内联函数。delete
、delete[]
new
、 malloc
、delete
、 free
:malloc、free 是库函数,而new、delete 是关键字
new
:内存分配成功,返回该对象类型的指针;分配失败,抛出 bac_alloc 异常。申请空间时,无需指定分配空间的大小,编译器会根据类型自行计算;申请空间时,返回的类型是对象的指针类型,无需强制类型转换,是类型安全的操作符;malloc
:成功申请到内存,返回指向该内存的指针;分配失败,返回 NULL 指针。在申请空间时,需要确定所申请空间的大小。申请空间时,返回的是 void* 类型,需要进行强制类型的转换,转换为对象类型的指针。union
:联合体,只有一个有效的成员,对联合体的不同成员赋值,将会对覆盖其他成员的值,联合体的大小为其内部所有变量的最大值,按照最大类型的倍数进行分配大小。volatile
:多线程巴拉巴拉的,类似线程锁。extern
:C 语言编写的函数14.-17.啥的从来没用到过QAQ
需要是引用传递,因为值传递首先需要调用拷贝构造函数创建一个类的对象。禁止套娃。
virtual fun()=0;
的类为抽象类不能实例化对象。类的对象存储指向虚函数表的指针实现
右值引用可以修改右值,借助 std::move()
转换左值引用为右值引用
int &&a = 10;
a = 100;
int b = 5;
int &&refb=std::move(b);
std::move()
大小:64位计算机占8个字节
const int *myptr = a
,a
可以是变量,只是限制不能使用常量指针修改变量a
值。int const * myptr = a
,myptr
本身不能改变即指向的地址不能改变,a
的值可以进行修改。int (*funptr)(int x, int y);
,funptr
可以指向函数int fun(int x, int y){return x*y;}
使用funptr = fun;
int * fun(){int * intptr = new int(10);return intptr;}
nullptr 具有数据类型,可以转换为任意类型的指针。
NULL 是0,函数重载调用时,会出现无法匹配的情况。
nullptr
并非整型类别,甚至也不是指针类型,但是能转换成任意指针类型。nullptr的实际类型是std:nullptr_t。
总结别人的解释https://zhuanlan.zhihu.com/p/79883965
c语言中
#define NULL ((void*)0)
c++语言中
#define NULL 0
NULL
是宏定义,在C++中,NULL不过是0,把它当成空指针只是一个无可奈何了。因为C++中不能将void *类型的指针隐式转换成其他指针类型。
int **myptp
,但是引用只能一级。(是否能为多级)int a = 10;
doubel b = static_cast(10);
通过“运行时类型检查”来保证安全性的。
去除 const 属性的转换。
reinterpret_cast 用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个bit复制的操作。
就是随便程序员转换,挂了自己负责。
自定义比较函数,重载运算法==
啥的。
memcmp
是逐个字节比较,然而可能存在内存对齐,对齐时候的补的字节是随机的。
参考https://blog.csdn.net/K346K346/article/details/85018985
template
:类模板在模板参数列表中可以有默认参数。c++11
之后类模板和函数都可以有。template
T fun(T x, T y)
{
return x+t;
}
int x,y;
fun(x,y);//隐式调用
fun(x,y);//显式调用
template
class AAA
{
public:
//构造函数
AAA(T a, T b)
{
this->a = a;
this->b = b;
}
//运算符重载
AAA operator+(AAA &c)
{
AAA tmp(this->a + c.a, this->b + c.b);
cout << tmp.a << " " << tmp.b << endl;
return tmp;
}
private:
T a;
T b;
};
Complex a(10, 20);//显式调用
template // Args 是模板参数包
void fun(T &t, Args&... rest); // 可变参数模板,rest 是函数参数包
template
void fun(T &t);
本质上是递归调用fun( T &t, Args&... rest)
,直达参数只剩一个调用fun(T &t)
结束。
#include
using namespace std;
template
void print_fun(const T &t)
{
cout << t << endl; // 最后一个元素
}
template
void print_fun(const T &t, const Args &...args)
{
cout << t << " ";
print_fun(args...);
}
int main()
{
print_fun("Hello", "wolrd", "!");
return 0;
}
/*运行结果:
Hello wolrd !
*/
类模板
template
class Test
{}
//全特化
template<>
class Test
{}
//偏特化
template
class Test
{}
函数模板
//普通模板
template
bool Compare(T1 a, T2 b)
{
return a == b;
}
//函数模板特化
template<>
bool Compare(const char* a, const char* b)
{
return strcmp(a,b) == 0;
}
模板
容器
迭代器
STL中了解一下底层实现
ennn再说吧