利用C++模板SFINAE特性解决编程规范构造函数问题

举报
技术火炬手 发表于 2020/07/20 16:35:46 2020/07/20
【摘要】 学习分享笔记

编程规范指出在构造函数里面不能做任何有可能失败的操作,比如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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。