*** 作系统导论:1.定义一个类的时候,我们显式或隐式指定该类的对象在拷贝、移动、赋值和销毁时做什么。
一个类通过以下五种特殊成员函数来控制这些 *** 作:拷贝构造函数、拷贝赋值运算符、析构函数、
移动构造函数和移动赋值运算符。其中后两类是在C++11中新增的。
这些 *** 作统称为拷贝控制 *** 作。
这些拷贝控制 *** 作如果用户不显式定义,编译器会帮用户定义,但编译器版本的行为可能就不能如用户所愿了。
2.默认初始化:定义一个变量时(或者说一个对象时),如果没有指定初值,则它会被执行"默认初始化"。
默认值是什么由各个变量的(对象的)类型决定。
3.默认构造函数:控制一个类型的默认初始化的构造函数。
4.合成的默认构造函数:编译器帮用户创建的默认构造函数。它会优先使用类内初始值为对象的各个成员赋初值。
否则会要求对象的各个成员执行其各自的默认初始化。注意,只有在该类型里没有任何其他构造函数时,
编译器才会帮用户创建"合成的默认构造函数"。
5.如果一个构造函数的第一个参数是自身类类型的引用,并且任何额外参数都有默认值,那么这个构造函数是拷贝构造函数。
6.拷贝构造函数的以一个参数往往都是得自身类型的const的引用,而且拷贝构造函数往往都不是explicit的。
7.与默认构造函数不同,即使类中定义了其他构造函数,在没有定义拷贝构造函数时,编译器也会帮用户定义合成拷贝构造函数。
8.那么什么是"拷贝"呢?鄙人认为本书中的"拷贝"一词往往等价于’ = ‘,即使用了’ = ‘的 *** 作就是一次拷贝 *** 作。
所以可以粗略的认为,拷贝初始化就是用’ = ‘来初始化对象的初始化。
直接初始化就是没用’ = ‘来初始化对象的初始化。呵呵。
9.一般情况下,合成拷贝构造函数所做的事情,就是将其参数的非static成员逐一拷贝到正在创建的对象的各个对应成员当中去。
每个成员的类型决定了如何进行拷贝:类类型用其拷贝构造函数进行拷贝;内置类型直接进行拷贝。
数组本来是不能拷贝的,但在这里,是数组的成员可以分解为一个一个的单独元素拷贝过去,
单个元素的拷贝方式则由元素的种类决定。
10.直接初始化和拷贝初始化的区别在现在更加明晰了。直接初始化,其实调用的是该类型的全部构造
函数里与所提供参数最匹配的那个构造函数,而拷贝初始化其实是调用了该类型的拷贝构造函数,
执行它,并在’ = ‘左边和右边的对象类型不同的时候进行类型转化。
11.除了使用’ = '定义变量(对象)时使用了拷贝初始化,在以下4种情况下也使用了拷贝初始化:
1将一个对象作为实参传递给非引用的形参 2从一个返回类型为非应用的函数返回一个对象
3用花括号列表来初始化一个数组中的元素或一个聚合类中的成员
4容器调用insert和push等类似的成员来为容器添加元素时
12.使用emplace的 *** 作来向容器里添加元素时,使用的是直接初始化而不是拷贝初始化。这是C++11新增的 *** 作。
13.在拷贝初始化时,编译器可以忽略和绕开拷贝构造函数,并在实际上执行直接初始化。但是,
这不意味着这个类型的拷贝构造函数可以不存在(比如,它不能是private的)。
1.int *x = (int *) malloc (sizeof(int));这一行里,堆和内存都被分配了一些内存。
2.C语言里的NULL只是一个值为0的宏罢了。
3.32位机器里int占4位,64字节机器里int占8位。
4.C语言里的sizeof()不是一个函数,而是一个编译时 *** 作符。在编译时,sizeof(int)就已经被替换为8。
5.段错误,指对内存犯的错误。如内存访问越界。
6.没有为变量分配足够的内存,会导致缓冲区溢出。这种情况往往不会报错,但是溢出的部分可能会
覆盖在其他变量的内存上,导致难以置信的危害。
7.语言的垃圾收集系统的存在也不能防止内存泄漏,因为你可能还在某处存在对某块内存的引用。
内存还是会变得越来越少。
8.短期使用的程序有些内存泄漏通常不会有什么坏的后果因为它马上就会运行结束,
然后给它分配的内存都会被 *** 作系统收回。但在服务器,甚至 *** 作系统本身中,
内存泄漏是完全不能容忍的。编写内核代码的人,工作是很辛苦的,因为要写对。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)