闲扯

众所周知,c++编程范式比较多, 实际工程中一般面向对象和泛型编程比较多, 有时候不同的项目组的喜好有差异导致代码的编程范式不同, 互相review的时候基本看不懂对方的代码(喜欢泛型的应该看面向对象的没啥压力, 但是没怎么用过泛型的看着一堆template就比较头疼); 看过的项目代码很少,不知道现在(现代)业界c++一般什么是最佳范式.

  • 泛型编程(Generic Programming) : STL大量使用, 核心是template class/Iterator class组合而成

  • 面向对象编程(Object-Oriented Programming): 通过对类的虚继承而实现了多态, 复杂的对象模型.

不考虑类的继承, 实际上一个template class涉及的方方面面知识点已经比较全面了, 因此列出相关的知识点权当笔记.

explicit

其实这个没什么好说的, 一个non-explicit构造函数本来就是比较别扭的, 保守一点直接加上explicit防止犯错的机会. 无论是转成类对象还是类对象转成内置类型, 都显示转换, 后者直接利用:

operator double() const {}

pointer-like classes

如果要找出一个STL中的类似class的话, 那么就是各个容器类的迭代器了. Iterator class或者说pointer-like class一般不单独使用, 而是附着在容器中, 方便同意操作, 比如有一个容器类:

class A { public: /// private:
    vector<int> vecs; };

为了方便对把类用于算法, 要求类提供诸如begin() 和 end()方法, 那么就需要在类内部嵌套一个迭代器类型了, 如下

class A { public:
    typedef A_iterator iterator;
    friend class A_iterator;
    iterator begin();
    iterator end(); private:
    vector<int> vecs };

然后对于迭代器的操作, 内聚到A_iterator中去实现, 当然STL为了统一所有迭代器操作, 对迭代器的实现是有要求的, 一般自己实现的迭代器起码应该提供解引用/自增(前置/后置)/相等等操作.

function-like class

不复杂的功能基本上可以被lambda表达式所替代, 而后者提供更好的可读性和等价的性能, 要不然代码中一堆函数对象类, 看着头晕;当然熟悉一下标准库中已内置的函数对象类还是很有必要的.

auto

减轻了很多心智负担, 而且c++14中, lambda表达式中也可以使用auto, 可以直接这么用; 一般搭配range for来用

auto multiply = [](auto a, auto b) {return a*b;};

对象模型

c++中类的大小取决于元素的类型和个数; 编译器对齐策略. 其中,c++的多态的实现有赖于虚函数表,对于没有虚函数的函数调用来说,静态绑定编译时确定调用方法, 而有虚函数的函数调用,则运行时确认.

  • 是否是虚函数,如果是,则会给虚函数表指针分配空间

  • 对于空类,编译器也分配了一个字节大小的位置

  • 考虑到字节对齐,编译器会自动在最后多分配一些空间(具体多少和32/64相关)

template class实现

  • 除了常规的构造/赋值/拷贝之外,和普通的类的区别在于,在类声明外的函数定义, template<typename X>也是限定符之一.

  • template class不仅能够传递变量类型, 同时可以传递函数对象(函数对象也是常量表达式的一种), 通过提供不同的方法而构造不同的类对象.


Ender
599 声望17 粉丝