标签:占用 比特 Locator allocator 超越 分配 建模 设置 面向对象设计
类空间大小计算
类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算在内的。
注意:
成员函数还是以一般的函数一样的存在。a.fun()是通过fun(a.this)来调用的。所谓成员函数只是在名义上是类里的。其实成员函数的大小不在类的对象里面,同一个类的多个对象共享函数代码。而我们访问类的成员函数是通过类里面的一个指针实现,而这个指针指向的是一个table,table里面记录的各个成员函数的地址(当然不同的编译可能略有不同的实现)。所以我们访问成员函数是间接获得地址的。所以这样也就增加了一定的时间开销,这也就是为什么我们提倡把一些简短的,调用频率高的函数声明为inline形式(内联函数)。
总结:
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
(二)类内部的成员函数:
内存对齐
面向对象设计原则05之------合成/聚合复用原则(CARP)定义:尽量使用合成/聚合,尽量不要使用类继承。合成是一种强的拥有关系(大雁和翅膀!),聚合是一种弱的拥有关系(雁群和大雁!)
尽量使用继承而不是聚合,因为继承使得类间的耦合性最小(错误)
因为:不要使用继承组建功能,而是使用黑箱复用(即对象组合),因为继承的层次增多,造成最直接的后果就是当你调用这个类群中的一个类时,就必须要把他们全部加载到栈中!(后果可想而知。)
1 c++中什么类型的成员变量只能在构造函数的初始化列表中进行
const对象或引用只能初始化但是不能赋值。构造函数的函数体内只能做赋值而不是初始化,因此初始化const对象或引用的唯一机会是构造函数函数体之前的初始化列表中。
2 C++ Struct 的区别
struct能包含成员函数吗? 能!
struct能继承吗?能!!
struct能实现多态吗?能!!!
Struct和c+++最本质的一个区别就是默认的访问控制:
struct的成员默认是public,class的成员默认是private
struct可以继承class,同样class也可以继承struct,此时继承访问权限是看子类到底是用的struct (public) 还是class(private)
3 判断两个结构体相等
可以重载“==”操作符。或者memcmp()函数,但是memcmp函数是逐个字节进行比较的,而struct存在字节对齐,比如char类型为1字节,字节对齐后扩充到4字节,但是这三个字节中间没有任何置0的操作。所以在用这个比较函数之前必须要之前要进行内存填充。字节对齐时补的字节内容是随机的,会产生垃圾值
类型
对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char
偏移量必须为sizeof(char)即1的倍数
int
偏移量必须为sizeof(int)即4的倍数
float
偏移量必须为sizeof(float)即4的倍数
double
偏移量必须为sizeof(double)即8的倍数
Short
偏移量必须为sizeof(short)即2的倍数
这个倍数(字节对齐数)可以利用宏定义来设置#pragma pack
4 STL
标准模板库,高效的C++程序库。STL的一个重要特点是数据结构和算法的分离。但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组;STL是基于模板,而不是封装,继承,虚函数(多态)。
STL中六大组件:
1)容器(Container),是一种数据结构,如list,vector,和deques
,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
2)迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象,Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。
3)算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
4)仿函数(Function
object)
5)迭代适配器(Adaptor)
6)空间配制器(allocator)
下面我将依次介绍STL的这三个主要组件。
根据C++的标准,STL的allocator,把对象的申请和释放分成了4步:
第1步:申请内存空间,对应函数是allocator::allocate()
第2步:执行构造函数,对应函数是allocator::construct()
第3步:执行析构函数,对应函数是allocator::destroy()
第4步:释放内存空间,对应函数是allocator::deallocate()
C和c++相互调用
C和C++编译器对编译函数符号的生成规则是不一样的(因为重载)
C调用C++,一个函数将C++类的使用封装起来,然后将它外部声明为C函数就可以了。使用extern "C"则是告诉编译器依照C的方式来编译封装接口,当然接口函数里面的C++语法还是按C++方式编译。
而C++调用C,extern "C" 的作用是:让C++连接器找调用函数的符号时采用C的方式
C语言的位域
所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
sizeof和strlen的区别?
strlen 是函数,sizeof 是运算符。
strlen 测量的是字符的实际长度,以‘\0‘ 结束。而sizeof 测量的是字符的分配大小。
比如:
char str[20] = "hello";
printf("strlen: %d\n", strlen(str));
printf("sizeof: %d\n", sizeof(str));
结果:
[root@localhost 0703]# ./hello
strlen: 5
sizeof: 20
2.内存的扩展方向:
1.递增地址:存放数据时, 自低地址向高地址依次存放, 例如栈
2.递减地址:存放数据时, 自高地址向低地址依次存放, 例如堆
int在内存中字节排布? 小端模式
占用4个字节,每个字节有8个比特位. 在所有被int类型占用的比特位中,左起第一个位(即最高位)就是符号位。int类型的符号位上,0表示正数,1表示负数。在32位操作系统下,其余后面31位是数值位。
123456
大端模式:从右向左读,123456
小端模式:从左向右读:654321
一般来说小端多用于C++/C 大端多用于JAVA
static的作用:
4.类中:
静态变量:类名.变量名直接引用 它和全局变量都存放在静态存储区
静态方法:类名.方法名直接引用
如果数据很少,深度学习算法性能并不好,因为深度学习算法需要大量数据才能很好训练处合适的参数,得到合适的模型。这种情况下,使用人工指定规则的传统机器学习占据上风。
特征工程:
机器学习中,大部分使用的特征都是由专家指定或根据先验知识确定每个数据域和数据类型。比如,特征可以是像素值,形状,纹理,位置,方向。大多数机器学习方法的性能依赖于识别和抽取这些特征的准确度。
深度学习算法是自学习。从数据中学习高层特征,同时也是超越传统机器学习的重要一步。深度学习本质上可以看作一个特征学习器,如卷积神经网络在底层学习如边和直线种种低层特征,然后是面部部分特征,最后是人脸的高层特征。
在无需另构特征情况下,传统的机器学习算法已经能够胜任日常的任务。
可解释性:
深度学习给图像描述自动评分,你会发现得分来判断是否接近人类评分水准。但它不能解释为什么给出这样的分数。在运行过程中,你可以发现深度神经网络的哪些节点被激活,但你不知道这些神经元是对什么进行建模以及这每层在干什么,所以无法解释结果。
机器学习算法按照翻译规则明确解释每一步做出选择的原因(如决策树),因此像决策树和线性/逻辑斯蒂回归这类算法由于可解释性良好。
标签:占用 比特 Locator allocator 超越 分配 建模 设置 面向对象设计
原文地址:https://www.cnblogs.com/FMOON/p/9379006.html