c++explicit关键字_java关键字instanceof「建议收藏」

c++explicit关键字_java关键字instanceof「建议收藏」c++11noexcept关键字作用c++2.0中,一条经典的规范是:尽可能地为一个函数加上noexcept声明,意味着程序员向编译器保证该函数不会发射异常

c++explicit关键字_java关键字instanceof「建议收藏」"

c++11 noexcept关键字作用

c++2.0中,一条经典的规范是:尽可能地为一个函数加上noexcept声明,意味着程序员向编译器保证该函数不会发射异常。

这条规范说的很对。那么,本文我们主要来探讨:

  • 为什么给函数加上noexcept会优化其性能?
  • noexcept的常见用法?
  • 你可能会觉得自己也不确定这个函数是否会在运行时发射异常,那么到底什么时机应该为函数加上noexcept可以获得最佳优化?

一、noexcept声明对函数性能的优化

这个原因从直观上理解应该是:既然开发者确保此函数不会发射异常,那么编译器也就没有必要为处理这个”可能“发生的异常添加一些事先预备好的目标代码,这在一定程度上减少了函数编译后生成的目标代码。

二、 noexcept的常见用法及注意事项

c++11和c++98对阻止异常抛出的写法不一样:

void func()throw(){ 
   }//c++98,这种写法并不能完全享受到上面提到的那种优化
void func()noexcept{ 
   }//c++11

在c++11中,noexcept的用法如下:

void func()noexcept{ 
   }//1. 
void func()noexcept(express){ 
   }//2. 

第二种写法将根据表达式的真假来决断函数是否发射异常,noexcept等价于noexcept(true)。

需要注意的是,如果承诺了func函数是不会抛出异常的,那么必须保证func调用的其他函数也是不会抛出异常的,否则无法保证func的noexcept性质。因此,我们可以百分百确定一个函数不会发射异常的情况是比较少见的!需要了解的是,c++11为所有类的析构函数都加上了“隐式”noexcept声明。

另外,假设我们承诺的noexcept函数在运行时真的发射了异常会怎么样呢?(一定要注意,如果使用了catch子句捕获并处理了异常,那不算发射异常!)我在GNU下测试过,运行时还是会抛出异常然后程序崩溃。只是在编译生成目标代码时做了优化而已。

void func()noexcept{ 
   
    int* a=nullptr;
    *a=2;//抛出一个异常 
}

bash输出:

zkcc@LAPTOP-OHBI7I8S:~/mytest$ g++ test_cast.cc -o test_cast && ./test_cast
Segmentation fault

三、为函数加上noexcept声明的最佳时机

直接给出建议:当你为一个类设计移动系列函数时,如果可以,最应该为其加上noexcept,以便此类在使用标准库容器时可以用移动操作来代替拷贝。

咋回事呢?移动操作加上noexcept与标准库容器的移动优化有啥关系呢?

以vector为例,很多标准库容器需要特定时机的扩容操作:把元素从旧内存拷贝到新开辟的内存,再析构旧内存中的元素。

针对这种情况明显可以用移动操作来优化之。(为什么移动操作比拷贝操作速度更快,什么时候会有明显的优化?这个问题我们之后也会讨论!)

但标准库的做法是:如果容器中类的移动操作函数带有noexcept声明,则使用移动操作来代替拷贝;如果没有noexcept声明,则用拷贝来完成扩容。

因此你会发现,将各种移动系列的函数设计为noexcept,会对标准库性能提升有巨大的帮助!

今天的文章c++explicit关键字_java关键字instanceof「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/77057.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注