直入主题
作为C++程序员你不知道这些技巧?这哪能行?赶紧来学学。 以下是我在平时项目开发中常喜欢使用的一些技巧,希望对你有所帮助。
(在恰当时候使用一些技巧能让你的代码变得更加美)
(一)do{}while(false)使用
在写代码的时候有没这种情况,伪代码:
void model()
{
if (条件1)
{
...; // ...其他代码
if (条件2)
{
...;
if (条件3)
{
}
}
}
other code; // 必须执行的代码
}
有时候可能会遇到这种情况,最后面的other code是必须执行的代码,然后上面又很多判断条件,一直if…if…if…,看着看着就辣眼睛了。
这时候可以考虑使用下do{} while(false); 伪代码:
void model()
{
do
{
if (!条件1) break;
...; // 其他代码
if (!条件2) break;
...; // 其他代码
if (!条件3) break;
...;
} while(false);
other code; // 必须执行的代码
}
while(false)让我们的代码只执行一次,但我们可以通过break让代码跳出该模块,而消除了某些情况下多次if导致的代码可读性差。
(二)union
联合体大家都有在书上看到吧?对于初学C++的小伙伴可能不了解为啥要用他。虽然不是啥新鲜技巧了,但还是说说吧!
在项目开发中我时常喜欢使用联合体来作为索引的转换,如你是名玩家那你所在的服务器ID,跟你的个人ID组合起来在全服中就是唯一值,那么要怎么拿到这个唯一值呢?
union RoleKey
{
struct {
uint32 nSerId;
uint32 nGuid;
}
uint64 nValue;
}
// 那么我们在这里获取64位的唯一值
const uint64 GetRoleKey(uint32 serverId, uint32 guid)
{
RoleKey key;
key.nSerId = serverId;
key.nGuid = guid;
return key.nValue;
}
利用联合体的机制我们很容易的将低32位设置为了服务器ID,高32位设置为了个人ID,最终通过联合体机制获得了64位唯一值。
(三)结构体初始化
正常情况下可能是这样的?
struct Model
{
uint32 id;
uint32 type;
uint32 param;
Model()
{
// 每次新增一个结构体我们都加一个构造函数来初始化
memset(this, 0, sizeof(*this));
}
};
那现在是怎么样的?不急不急,使用一些小技巧可以让我们节省代码的同时不容易犯错,往下看。
// 模板类
template <typename T>
class ZeroStruct
{
public:
ZeroStruct()
{
memset(this, 0, sizeof(T));
}
};
// 没错现在是这样的
struct Model : ZeroStruct<Model>
{
uint32 id;
uint32 type;
uint32 param;
};
通过继承模板类的方式来达到很方便的初始化,看个人喜好使用。
(四)tuple的使用
没错这是元组,学过其他语言的童鞋们应该很羡慕其他语言(如:python),他们有元组,可以支持任意类型的数据类型。 我在这里提出只是让不了解的童鞋们知道C++11后,C++也支持了元组,它就是——tuple。
为了简单理解啥是元组,其实我们可以拿pair来做比较,pair支持两个参数如:std::pair<int, std::string> _pair; 而tople是可很多参数的,具体看如下代码。
using testTuple = std::tuple<int, float, string>;
void test()
{
static const std::vector<testTuple> testVec = {
make_tuple(1, 1.0f, "is -> 1"),
make_tuple(2, 2.0f, "is -> 2")
};
for (auto& e : test)
{
const testTuple _tuple = e;
// 通过get方法即可获取
int nNum = get<0>(_tuple);
float fNum = get<1>(_tuple);
std::string str = get<2>(_tuple);
}
}
通过使用tuple,很多情况下我们可以不使用结构体了。
(五)enum 中加class
如果全局中使用enum,很可能导致枚举类型的命名冲突,这时加class能很好的防止命名冲突,非常推荐使用。
enum class ModeType
{
Type_One = 1,
Type_Two = 2,
Type_Three = 3,
};
(六)Lambda
对于lambda的使用可以看我之前的文章
C++11 lambda表达式使用场景解析
(七)宏
前面文章也有对宏的一些用法如:
C++宏的黑科技用法《结构体字节序自动转换》
先总结这几点,后续如果有其他好用的技巧我会更新上来,也欢迎童鞋们有好的技巧能分享给我。