为什么拥有C语言基础的人,依然学不会C++?
当你认为 C++ 是面向对象的语言的时候,你就永远学不会 C++。
恰恰大部分学了 C 的人,都会认为 C++ 不过是 C 上加了“对象”。既然是 C with class, 他自然就很自信的认为自己很快就能学会C++。
C++ 不过尔尔。
----
但是,当他有一天,需要使用C++的时候,很快他就会感到巨大的挫败感。
因为C++除了 C with Class ,剩下的东西他没一个能懂的。
C++ 真的是太复杂啦!
这就是大部分人 C++ 从入门到放弃的原因。
----
如果放弃自以为是的面向对象的成见,好好的学习 C++,就会发现, C++其实是个面向“概念”编程的语言。
C++ 的一切特性,都是为了 0 开销抽象 “概念”。
为何会有模板?
因为,同一个概念,用同一份代码。而不管这个概念背后的真实数据类型。比如 std::sort, 他就是排序。只要能比较大小的,就能排序。你管他是 int 还是 char 还是float, 甚至连 string 都能排序。只要能满足 “可比较大小” 这个概念的,都要能排序。
既然排序,就得有容器。排序排序,得有个容器,把东西放里面排排放,那才有顺序的概念。
于是就有了 “容器” 的概念。为了操作容器,就要对容器进行更高程度的抽象,于是就有了 “迭代器”的概念。迭代器,就是用来访问容器里存储的对象的。是容器的抓手。
有了容器,就有了“对象”生命期的管理需求。对象放入容器,拿出容器,它到底何去何从。
于是就有了右值引用和左值引用的概念,这样就能设计出 拷贝构造和移动构造。
有了拷贝和移动的概念,才能设计出性能更好的容器。对象是被移动到容器里的,而不是拷贝进去的。这就大大降低了使用容器存储“大对象”的开销。
这些都有了,又发现,如果用错了对象,对象和模板希望的“概念”不匹配,编译出错就会非常疯狂。
于是就有了 "concept" 关键字。加上了模板参数约束功能。
很多时候,一个通用概念下,总会有一些“特例”。为这些特例按排单独的代码,不共享通用的模板代码,就可以更好的“优化”性能。于是就有了 “模板特化” 功能。
模板特化,是为了更好的实现概念。比如 容器一般会对 普通的“对象” 和 简单的内置类型对象,使用不同的代码。因为内置类型没有“构造函数”。于是,容器的模板,就会对简单类型进行特化。这样的特化代码,对无构造函数,无析构函数的对象,进行针对性的优化。
但是,无构造函数的,难道只是内置类型吗? 用户写的对象,也可以无构造函数。于是,这种模板特化,就不是为具体类型进行特化,而是对某个细分的“概念”进行 一半的特化。这种一半的特化,就叫 模板偏特化。 也是为了更好的实现 面向概念编程。
所以你看,一切 学不会的 C++ 特性,都是因为他还在使用“面向对象”这种思维方式。