标签:bug thread 基本原则 信息 new val bsp 要求 空间
当我们定义一个类的时候,如果是一个空的类,编译器默认提供了默认构造函数,拷贝构造函数,拷贝赋值函数,内敛析构函数。
如果派生出一个新的类继承自空类,编译器生成的是一样的,不过在构造的时候会调用基类的构造函数。
已经写过了部分类函数,编译器会将剩下的函数给你默认生成。
如果有自己的构造函数,编译器会生成其他构造函数,但是不会生成默认构造函数。
如果没有在最后写return 0,会在最后默认调用exit(0),因此不写return 0也是可以的。
C++本身有异常,不一定是在最后进行返回的。
const 不变性的引入,multithread是密不可分的。最早是在c++中引入的
constexpr 在编译器得到足够多的信息后,可以在编译期将结果得到。
decltype和auto很类似,差别之一就是没有进行赋值操作,用到的仅仅是类型本身呢。
如果表达式加上一个小括号 ,类型就是该类型的引用,就需要引用初始化,否则就会报错了。
auto也可以,不过要显示的指定引用类型。
更多时候decltype是和auto一起使用的,auto放在前面,同时使用decltype尾后返回这种形式。
在进行dynamic_cast类型转换的时候,如果是指针类型,转换失败,会抛出null,如果是引用类型会抛出异常。
class中的函数默认是inline,在外边实现的时候也需要加上inline
(void*) 0 C语言中的define
static的用法
在文件里面用法
在文件的全局范围内可见的,是在程序编译的时候内存空间都已经分配好了,
定义在函数里面,相当于函数有一个状态。
static在类和struct的用法 在类中static仅仅相当于是声明,还需要在外部进行类的定义
这个时候才会分配内存空间才能找到这个变量。
static_assert 和 assert类似,不过就是在编译器还没有到连接的过程如果没有满足要求就报错了。
assert实在运行的过程才会发现问题,assert是一个宏,在debug和release下面的行为是不一样的,在release下面会自动的进行忽略。
static_cast没有任何的性能损失,告诉编译器就是要这么进行强制类型转换。
thread_local c++11引入的关键字,方便多线程编程。
----------------------------------------------------------------------------------------------------------------
C++98 C++11
类的前置声明, 是不完全类型,void 也是不完整类型,仅仅是类型的声明。
前置声明的好处,为什么要用前置声明。
作为基、 类成员、类成员所需要的东西,这些情况是不能省略掉的,
其他情况下比如说参数接口或者是函数返回值,只需要知道是什么就行了,也就是有声明就足够了。
类在编译的过程最需要的就是类的大小了。
构造和析构
C语言为什么不会有析构这样的过程,之所以没有析构是因为C语言的控制流是明确的
但是C++的程序的控制过程中,可能因为抛出异常而打断了这样的过程,这个时候控制的资源就应该被释放掉。
Java 的资源释放是不明确的,可能在你最繁忙的时候系统会释放资源,这个时候就卡顿了。还有就是程序中管理的资源不仅是内存,还有文件句柄,已经连接等等。这些也都是需要进行手动进行管理的。
C++有析构函数,内存在什么时候释放对于程序员来讲是明确的,无非有两种情况,一种是类自动析构的时候,new出来的资源delete的时候会进行释放。
C++中的3条基本原则
rule1 类成员中有指针类型的成员变量的时候,必须要写一个析构函数来管理资源。不能使用编译器默认的析构函数,默认的析构函数会默认的调用类成员的析构函数,同时如果这个类是从其他类派生过来的,就会调用其父类的析构函数。
rule 2 rule3: 如果类是可以拷贝的,需要写出拷贝构造函数和拷贝赋值函数。如果没有写会自动生成一个,生成的这个会仅仅对类成员进行拷贝,默认的拷贝是值拷贝。
如果不需要C++98的做法是privete私有化,并且仅仅是函函数,这个实在运行的时候才进行决策。
C++11中的做法是使用=delete关键字,这种情况会在编译时候进行决策。
什么是左值什么是右值?右值是不能取地址的,左值是可以取地址的,这个是最明显的差别。
C++中之前会大量进行对象的拷贝工作,函数的传入传出会大量的调用拷贝构造函数。
这种情况下,编译器是可以做优化的,称为是optimize value。
右值引用,C++11中引入的新概念。C++中明确了返回左值或者是返回右值是能够区分出来的。
既然是能够区分出来的就可以利用它, 减少对应的拷贝就是一个很大的问题了。
std::move就是将一个左值变成一个右值。右值就相当于是一个临时变量,临时变量不能够取引用,但是可以取const引用。函数参数为const引用的时候函数参数可以为左值,右值,临时对象,const引用,都是可以的,简直就是万能的参数。
如果没有写移动构造函数,默认就是调用拷贝构造函数,因此右值引用相当于是一个临时变量,而拷贝构造函数的参数允许接受一个临时变量,因此默认会调用拷贝构造函数。
rule4 rule5:
在拷贝构造函数传入一个右值,现在有能力区分传入的是左值还是右值了,以前是没有能力进行区分是左值还是右值的。
右值的拷贝构造函数要做哪些东西呢?
就是交换指针变量,同时将右值的指针变量变为NULL。
绝对不要在析构函数中抛出异常
编译器生成的析构函数默认是inline的,并且生成的是noexcept的。并且不会做任何的东西,不会包含try catch类似的语句在里面。自身析构结束之后还会调用成员函数的析构
38个部分
标签:bug thread 基本原则 信息 new val bsp 要求 空间
原文地址:https://www.cnblogs.com/randyniu/p/9277630.html