介绍typedef 好的文章 https://zhuanlan.zhihu.com/p/81221267 和 https://liam.page/2017/02/05/pointer-in-C-and-Cpp/
COM"自身是一个很复杂的概念,是微软当时为了让Office能够在办公软件当中胜出,所开发出来的一种技术。在Office当中使用的基于"COM"的技术主要有"OLE"和”DDE“。前者是嵌入式对象,就是我们可以把一个视频、或者一个别的什么原本Office当中不支持的文件,放到Office文档当中。然后这个东西就会显示为一个图标,或者是一个静态的图片(snapshot),双击这个图标或者这个静态的图片就会启动能够支持这个格式的软件对其进行播放或者编辑。这种播放或者编辑有两种形式:一种是in place,就是直接在Office文档当中进行,另一种是standalone,就是在Office之外进行。in place的时候,其实是在后台启动能够支持这种格式的一个程序,但是隐藏其窗口。然后把Office当中的一小块客户区域(就是之前我们用过的Rect所定义的一个矩形区域)传递给这个后台程序,让其负责处理这块区域的绘制和用户输入。也就是说,在Office程序的WM_PAINT事件的处理当中,将Office窗口的整个客户区域分割为由自己绘制的部分和由OLE绘制的部分,由OLE绘制的部分通过COM技术传递给后台应用进行绘制。比如我们嵌入的OLE对象是一个视频,那么当你在Office文档内播放这个视频的时候,实际上后台会启动Windows Media Player,只不过它的界面是隐藏的。Windows Media Player对视频进行解码播放,只不过和平常不一样的是,最后画面不是画在Windows Media Player自己的窗体上,而是画在Office文档当中的一块矩形区域当中。
最常见的应用就是在PPT里面放一个视频,或者放一个Excel表格,Word文档什么的。这个其实就是用的"OLE"技术。
而”DDE“大部分和"OLE"类似,所不同的是这个对象是单独存放在磁盘上,而不是嵌入到Office文档当中进行保存的。我们将一个Excel拖入到PPT的时候,Office会问我们是作为嵌入式对象,还是链接。嵌入式对象就是"OLE",而链接就是"DDE"。“DDE” 的特点是你可以随时在外部编辑那个文件,而改变会自动反映到使用“DDE”链接进的那个文档当中。也就是说,如果你用“链接”的方式把一个Excel放入PPT,那么后面如果你修改了那个Excel,PPT里面的那个Excel对象的数据也会跟着变。
除了这种应用,Windows服务,DirectX 3D当中所用的filter,.NET技术,IE Browser所用的插件,Office所用的插件,等等,都是基于"COM"技术。”COM“技术还有后继的"COM+"技术以及在多个电脑上分布式处理的”DCOM“(在Windows Server当中我们可以由一台服务器部署管理其它服务器,就是靠着“DCOM”) 技术。
1 malloc /new 申请内存慢的原因
当我们调用malloc/new进行heap分配的时候,并不是我们的线程直接杀入内核,去领一块内存出来。而是我们提交一个申领申请,放在放申请单的盒子里,然后等。操作系统方面按顺序处理这些申请,处理完了将处理结果放在处理结果盒子里,然后叫我们的号让我们去领。这个过程和我们在生活当中到特权机关去办事很类似。
虽然这些系统API调用看起来都是同步的,但实际上这是一个异步操作,只不过在操作完成之前,我们的线程会被block住,操作完成了,线程unblock,函数返回,看起来就像普通函数调用那样,其实这是一个比较复杂的过程。
而且在这个过程当中的参数传递,一般情况下都会发生拷贝。这是因为操作系统和用户程序分别工作在不同的地址空间,因此直接传递指针(地址)也是没有什么意义的。
因此,提高程序在CPU端的执行效率的一个重要手段,就是要减少系统调用。在程序初始化阶段就一次申领所需的资源,然后自己内部进行分配管理,这就是一种常用的减少系统调用的方法。
2 内敛函数
优点:
1 由于函数调需要各种指令,而内敛函数消除了函数调用过程中所需要的各种指令,包括在堆栈或者寄存器中放置参数,调用函数指令,返回
函数过程,获取返回值,从堆栈中删除参数并恢复寄存器等。
2 由于不需要寄存器来传递参数,因此减少了寄存器溢出的概率。
缺点:
使用不当的话造成代码膨胀(也就是生成的可执行程序会变大)影响cache对数据的命中。
2 noexcpt :
1 功能实际上与 throw()一样,c++14才有的,当一个函数被 noexcept修饰时候,如果该函数有异常,会
直接调用,terminate 终止程序(用的也是c++14 实际测试并未发现啥区别). 到c++17,throw 与 noexcpt 已经一样了.
2 noexcept implies no compile-time check。
会生成比较优化的代码,但是也不能随意使用。用在类的 移动 构造函数上可以在传递该类对象的时候调用移动构造函数提高性能(比如vector当中)。
3 智能指针
独占式指针
unique_ptr ,没有拷贝构造函数和 赋值构造函数,有移动构造函数,因此只可以用来转移资源。
从源码中可以看到:
unique_ptr(unique_ptr&& Right); //移动构造函数
template <class T2, Class Del2> unique_ptr(unique_ptr<T2, Del2>&& Right);
unique_ptr(const unique_ptr& Right) = delete; //拷贝构造函数(禁止使用)
unique_ptr& operator=(const unique_ptr& Right) = delete;//赋值构造函数(禁止使用)
另外:移除释放智能指针里面托管的资源调用reset 函数,而不是 release()(使用relese会还要调用delete)
比如下面这样 https://stackoverflow.com/questions/25609457/does-unique-ptrrelease-call-the-destructor
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw;
而用reset
auto v = make_unique<int>(12); // manages the object
v.reset();
4 右值引用与完美转发
std::move 与 std::forward
移动构造函数才会造成对象的转移,而move 和forward 都不会。
左值引用和右值引用都是属于引用,修改引用值都会对原值造成影响。
const 左值引用 可以绑定 右值。
右值引用出现的原因:
1 为了解决 大的对象进行转移资源,造成的需要分配内存问题,通过右值引用可以转移资源。
2 给右值的引用生命力,可以修改右值。有了右值引用,不用const 也能绑定右值了,
std::move 作用可以把左值引用变成右值引用方便进行转移。
std::move 并不会把值移走,而是会实现了右值引用。 std::move 的作用是让调用构造函数的时候告诉编译器去选择移动构造函数。
td::forward 与 std::move 的区别是,move 会无条件的将一个参数转换成右值, 而 forward 则会保留参数的左右值类型
std::forward 可以用来解决 智能指针赋值时候引用计数会增加1个的问题。
5 explicit
一般用在修饰函数 表示禁止隐式转换发生,下面的代码可以清楚的表示:
class Foo {
public:
explicit Foo(int x);
};
class Bar {
public:
Bar(int x);
};
void yourCode()
{
Foo a = 42; //Compile-time error: can't convert 42 to an object of type Foo
FBar b = 42; ///OK: calls Bar::Bar(int) passing 42 as an argument