利用C++模板SFINAE特性解决编程规范构造函数问题
【摘要】 学习分享笔记
编程规范指出在构造函数里面不能做任何有可能失败的操作,比如new/open申请资源:
规则1.6.2:构造函数内不能做任何有可能失败的操作
构造函数没有返回值,不能做错误判断,因此在构造函数内,不能做任何有可能失败的操作。
下面的代码中,open、new、ConnectServer都有可能失败,这些操作不应该放在构造函数内。
遵守这条规则的方法有二段式构造,也就是在new之后调用onConstruct/init函数去分配资源。但是提供init/onConstruct函数会导致忘记调用、重复调用等问题,现提供模板函数包装new实现。
template<typename U> static auto callOnConstruct(U* obj) -> decltype(obj->onConstruct(), int()) { return obj->onConstruct(); } template<typename U> static auto callOnConstruct(...) -> int { return 0; // return 0 for succuess } template<typename T, typename ...Args> T *Construct(Args&& ...args) noexcept { T *obj = new T(std::forward<Args>(args)...); if(callOnConstruct<T>(obj) != 0) { // onConstruct failed, loge! delete obj; return nullptr; } return obj; } template<typename T, typename ...Args> std::shared_ptr<T> make_shared_construct(Args&& ...args) noexcept { std::shared_ptr<T> spObj = std::make_shared<T>(std::forward<Args>(args)...); if(callOnConstruct<T>(spObj.get()) != 0) { // onConstruct failed, loge! return nullptr; } return std::move(spObj); }
之后就用Construct<T>(args...)来代替new T(args...),用make_shared_construct<T>(args...)来代替std::make_shared<T>(args...),构造好T后会根据T是否定义onConstruct方法而自动调用(没有就不调用了)。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)