本篇文章给大家分享的是有关深入浅析C++中的const,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
在抽象的最高层次上,const做两件事:
* 一种保护你自己的方式(类似于private)
* 对编译器的一种指示,表明标记为const的对象适合于程序的数据段。换句话说,属于只读数据(ROM-able)。
可以通过例子来看下const的应用。第一个例子中,使用const覆盖了整个例子:
void fun(int i, std::string const & str) { i = 0; //ok. str = ""; //error! int const n = 42; n = 2; //error! }
第二种情况只适用于静态初始化的名称空间-作用域变量(又称全局变量):
int const pi = 3; //ROM-able std::vector<int> const ivec = {/* ... */}; //Not ROM-able, might allocate.
对声明为const的变量的任何写操作都被显示为未定义行为。这支持const全局变量在ROM中的位置。
如果一个变量定义在ROM中,对它的写操作很可能会使程序崩溃,这取决于平台。如果一个变量不在ROM中,对它的写操作只会改变它的值。这两种情况的结合就是为什么对const变量执行写操作的行为是未定义行为而不是错误。
如果真的需要改写一个const变量的值,可以通过`const_cast`来改写:
void fun(int i, std::string const & str) { i = 0; //ok. const_cast<std::string &>(str) = ""; //Also ok (maybe). }
然而,const_cast并不能避免你在尝试写入声明为const的变量时永远不会遭遇未定义行为的陷阱。
std::string str = ""; fun(0, str); // Ok. std::string const const_str = ""; fun(0, const_str); // Undefined Behavior!!
因此,只有在确实需要时才使用const_cast,并且只有在知道要写入的底层变量是如何声明的情况下才使用。
**那么,究竟在什么时候什么地方使用const?**
答案就是**Everywhere**。将每个变量声明为const,除非您知道它将被写入。更一般地,在编译器接受的任何地方添加const。
int foo(int arg) { int const x = compute_intermediate_result(arg); int const y = compute_other_intermediate_result(x); return something_computed_from(x, y); }
为了优化目的,编译器通常不能使用一致性进行优化。
int get_value(some_class const & x, int const at) { int offset = compute_offset(at); return x[offset]; }
此时,在这些函数参数中使用const对优化器没有帮助。x上的const不起作用,因为x已经通过引用传递了。没有x的副本,编译器不知道x是否声明为const。在参数at上的const不能帮助我们,因为at是一个拷贝,它可以以任何方式装入寄存器。
如果编译器可以看到const对象的声明,它有时可以使用其一致性进行优化。
std::vector<int> const vec = { 1, 2, 3 }; int main() { // This may generate code that indexes into vec, or it may generate // code that loads an immediate 2. return vec[1]; }
如果您想保证这样的优化,您可以在c++11或以后的版本中使用constexpr。使用constexpr声明的变量只对可以静态初始化的类型进行编译,因此,如果编译了它,就会得到一个ROM-able的对象。
constexpr std::array<int, 3> arr = { 1, 2, 3 }; int main() { // This generates code that loads an immediate 2 on every // compiler I tried. return arr[1]; }
constexpr只处理字面常量类型(literal types)。这些类型与你可能在C中找到的类型相似。任何被声明为const的int或其他整数值都可以像文字一样使用。
void foo(int const arg) { int const size = 2; int array_0[2]; // Ok. int array_1[arg]; // Error! arg is a runtime value. int array_2[size]; // Ok. }
如果声明一个类成员static const,就很像声明一个全局const变量。
int const global_size = 3; struct my_struct { static int const size = 2; }; std::array<int, global_size> make_global_array() { return {}; } std::array<int, my_struct::size> make_my_struct_array() { return {}; }
但因为这是c++,所以有个问题。如果定义的static const整数值超越界限,则它可能无法被当作字面常量使用,例如一下的例子。
struct my_struct { static int const size; }; std::array<int, my_struct::size> make_my_struct_array() // Error! { return {}; } int const my_struct::size = 2;
这是的错误时因为编译器在解析foo()时不知道要为my_class::size使用什么值。如果你希望像使用全局const整数值一样使用static const整数值,请始终将它们声明为内联(inline)。
以上就是深入浅析C++中的const,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。