什么时候你该考虑使用C++模板?

Posted by admin on 2020-01-02

C++支持模板,但是不是每个程序员都能用好模板。听我一句劝,如非必要,不要使用。但是,模板确实也是大杀器,否则还会出现泛型编程吗? 本文聊聊,何时你该考虑用模板?

设计类库的时候

对于C++的老兵,这一点很容易想到。无论是STL还是Boost都大量使用模板,有些用法简直到了惊天地泣鬼神的地步。令人叹为观止。
所以,如果你也在设计一个类库,你的类库也希望有泛类型的支持,那么你要考虑使用模板。

可变长度数组

比如你要设计一个类VarChar,这个类需要存储不定长度的字符。
1.采用动态分配的方式,伪码:

1
2
3
4
5
6
7
8
9
10
11
class VarChar
{
bool set(const char* str, int strLen)
{
pChars = new char[strLen];
....
strncpy(pChars, str, strLen);
}
const char* get(){return pChars;};
char* pChars;
}
这样实现是可以的,但是你将不得不妥善管理你从堆申请的的动态内存。虽然你可以用智能指针缓解你的焦虑,但是智能指针也不是万能的。 2.普通栈分配的方式
1
2
3
4
5
6
7
const int MAX_VCHAR_LEN = 1024;
class VarChar
{
...
char content[MAX_VCHAR_LEN];
}

这种实现,避免了内存管理的焦虑,但是带来了新的焦虑:空间浪费和可能不足。 字符的空间占用恒定为1024字节。 既不能支持更多的字符,也不能节省分毫。如果减小MAX_VCHAR_LEN,意味着所支持字符串的长度减少;如果增大,则意味着可能更多的空间浪费。如此两难境地,用模板可以轻松解决。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <int size=64>
class VarChar
{
...
char content[size];
}

int main()
{
VarChar<16> char16;
VarChar<128> char128;
VarChar<1024> char1024;

}
> 如果VarChar对象存在于栈空间,size过大需要防止栈溢出。

为了追求效率

因为模板在编译阶段,会进行代码展开,所以效率上他会比一些动态模式高效。有时候为了追求效率,可以考虑用模板展开替代多态或者虚函数。

总结

针对C++而言,模板在某些场景下仍然发挥着不可替代的作用。掌握模板这一利器,是C++进阶的必由之路。