700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C++ 技巧 杂物间

C++ 技巧 杂物间

时间:2022-11-04 08:38:01

相关推荐

C++ 技巧 杂物间

C++杂物间

1. 概述2. incline3. explicit4. transfer of control bypasses initialization of: -- variable "sync"5. std::accumulate()6. String和char * 的问题7. 函数指针8. 使用宏进行数组拷贝9. memcpy函数10. lambda表达式11. mutex线程锁12. thread学习13. 使用宏进行类成员函数定义

1. 概述

整理收集一些阅读源代码时看到的C++技巧。

2. incline

内联函数,对于简短、运行时间短的函数可以使用,需要满足无递归、无循环的条件。

普通函数:会使用栈,对局部变量、函数返回地址、形参、实参进行处理。

内联函数:直接将函数体插入到调用语句处。

incline void Test(int n){//定义函数为内联函数std::cout<<n+1<<endl;}

3. explicit

explicit显式关键字,用于只有一个参数的构造函数或者含有n个参数但是具有n-1个默认参数值的构造函数,表明该构造函数是显式的, 而非隐式的, 相对应的关键字是implicit,隐式的,默认情况下类构造函数的声明为implicit。

explicit Test(int n) //explicit(显式)构造函数{num = n;}

4. transfer of control bypasses initialization of: – variable “sync”

谷歌翻译解释为

控制权的传递绕过了以下各项的初始化:-变量“ sync”(在第161行声明)

代码为,提示在初始互sync时出现问题,查找其他博客发现是因为switch语句出现了问题。参考

switch(m_dev_){case MTI_SBG:printf("MTI_SBG sync callback");typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Imu,sensor_msgs::Imu> MySyncPolicy;message_filters::Synchronizer<MySyncPolicy> sync(MySyncPolicy(10),*imu_mti_sub,*imu_sbg_sub);//10这里出现问题sync.registerCallback(boost::bind(&DNC::MTI_SBG_callback,this,_1,_2));//must follow with spin();while(ros::ok()&&(!m_chg_dev_)){ros::spinOnce();}break;

解决办法就是:在switch的每个分支上加上花括号{},或者把switch语句改成if/else。这里我加上了{}。就没有报错了

switch(m_dev_){case MTI_SBG:{printf("MTI_SBG sync callback");typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Imu,sensor_msgs::Imu> MySyncPolicy;message_filters::Synchronizer<MySyncPolicy> sync(MySyncPolicy(10),*imu_mti_sub,*imu_sbg_sub);//10这里出现问题sync.registerCallback(boost::bind(&DNC::MTI_SBG_callback,this,_1,_2));//must follow with spin();while(ros::ok()&&(!m_chg_dev_)){ros::spinOnce();}break;}

5. std::accumulate()

这是在数据校验代码中看到的,使用前面数据的累加和来进行校验,使用了**accumate()**模板函数,比较方便

return data[length() - 1] ==std::accumulate(data, data + length() - sizeof(sum), sum);

这是原定义

/*** @brief Accumulate values in a range.** Accumulates the values in the range [first,last) using operator+(). The* initial value is @a init. The values are processed in order.** @param __first Start of range.* @param __last End of range.* @param __init Starting value to add other values to.* @return The final sum.*/template<typename _InputIterator, typename _Tp>inline _Tpaccumulate(_InputIterator __first, _InputIterator __last, _Tp __init){// concept requirements__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)__glibcxx_requires_valid_range(__first, __last);for (; __first != __last; ++__first)__init = __init + *__first;return __init;}

6. String和char * 的问题

出现报错信息

deprecated conversion from string constant to ‘char*’

解决办法

将函数参数类型由char*改为const char

7. 函数指针

在LinkTrack中看到对函数指针的使用,比较有用,可以关注一下

这是在结构体中的声明

uint8_t (*const unpackData)(const uint8_t *data, size_t dataLength);

这是需要的函数定义

static uint8_t unpackData(const uint8_t *data, size_t dataLength) {assert(nltNodeFrame1_.kFixedFrameLength == sizeof (frame_));if(dataLength < nltNodeFrame1_.kFixedFrameLength || data[0] != nltNodeFrame1_.kFrameHeader || data[1] != nltNodeFrame1_.kFunctionMark) return 0;size_t frameLength = FRAME_LENGTH(data);if(dataLength < frameLength) return 0;if(!verifyCheckSum(data,frameLength)) return 0;static uint8_t initNeeded = 1;if(initNeeded){memset(nltNodeFrame1_.data.node,0,sizeof(nltNodeFrame1_.data.node));initNeeded = 0;}memcpy(&frame_, data, nltNodeFrame1_.kFixedFrameLength);nltNodeFrame1_.data.id =frame_.id;nltNodeFrame1_.data.localTime =frame_.localTime;nltNodeFrame1_.data.systemTime =frame_.systemTime;nltNodeFrame1_.data.voltage = frame_.voltage / kVoltageMultiply_;nltNodeFrame1_.data.validNodeCount = frame_.validNodeCount;Node1_Raw rawNode;for(size_t i=0;i<frame_.validNodeCount;++i){if(!nltNodeFrame1_.data.node[i]){nltNodeFrame1_.data.node[i] = malloc( sizeof(NLink_LinkTrack_Node1) );}memcpy(&rawNode,data + nltNodeFrame1_.kFixedFrameLength + i*sizeof(Node1_Raw),sizeof(Node1_Raw));NLink_LinkTrack_Node1 *node = nltNodeFrame1_.data.node[i];node->role = rawNode.role;node->id = rawNode.id;TRANSFORM_ARRAY_INT24(node->pos,rawNode.pos,kPosMultiply_)}return 1;}

最后就是赋值

NLink_LinkTrack_NodeFrame1 nltNodeFrame1_ = {.kFixedFrameLength = 27,.kFrameHeader = 0x55,.kFunctionMark = 0x03,.unpackData = unpackData};

实际调用时

void NLT_ProtocolNodeFrame1::updateData(const uint8_t *data){nltNodeFrame1_.unpackData(data, length());}

8. 使用宏进行数组拷贝

感觉这个代码很好使的样子,先做个标记。

#define ARRAY_ASSIGN(DEST, SRC) \for (size_t _CNT = 0; _CNT < sizeof(SRC) / sizeof(SRC[0]); ++_CNT) { \DEST[_CNT] = SRC[_CNT]; \}

9. memcpy函数

这是原始定义

/* Copy N bytes of SRC to DEST. */extern void *memcpy (void *__restrict __dest, const void *__restrict __src,size_t __n) __THROW __nonnull ((1, 2));

这是一个使用示例

memcpy(&frame_, data, nltNodeFrame1_.kFixedFrameLength);

10. lambda表达式

这只是一个范例,先将就着看,以后遇到其他的再查?

[ capture list ] (parameters) -> return-type { method definition}

[](){}

std::sort(sortInfos_.begin(), sortInfos_.end(), [](SortInfo a, SortInfo b) {if (a.headerIndex < b.headerIndex)return true;else if (a.headerIndex == b.headerIndex) {if (a.protocol->length() < b.protocol->length()) {return true;}}return false;});

对于sort()有

/* @brief Sort the elements of a sequence using a predicate for comparison.* @ingroup sorting_algorithms* @param __first An iterator.* @param __last Another iterator.* @param __comp A comparison functor.* @return Nothing.*/sort(_RandomAccessIterator __first, _RandomAccessIterator __last,_Compare __comp)

对于lambda表达式指定返回类型,可以使用 -> int

[] (int x, int y) -> int {int z = x + y; return z; }

如果需要进行其他值,

可以使用

[&b] 引用b[=a]值传递a

11. mutex线程锁

参考链接

12. thread学习

使用join,等待子线程结束再继续执行

不使用join,直接向下执行,可能子线程未执行完毕

都挺好的,可以看看。

boost::thread的六种使用方法总结

C++ 菜鸟之路 (四) boost::thread 多线程全解析

13. 使用宏进行类成员函数定义

宏定义

#define MEMBER_PARAM_SET_GET(member, type, name, qualifier, setqualifier, getqualifier)\getqualifier: inline type get##name() const {return member.get##name();}\setqualifier: inline void set##name(type name) { member.set##name(name);}

类中定义,存在setgenerateMap(bool),getgenerateMap()两种成员函数

/**generate an accupancy grid map [scanmatcher]*/MEMBER_PARAM_SET_GET(m_matcher, bool, generateMap, protected, public, public);

具体使用

gsp_->setgenerateMap(false);

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。