Const Qualifier
2022/2/12 23:48:13
本文主要是介绍Const Qualifier,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Initialization and const
1.Because we can't change the value of a const obeject after we create it, it must be initialized.
- We may use only those operations that cannot change an object.
int i = 42; const int ci = i; // ok:the value in i is copied int ci int j = ci; // ok: the value in ci is copied into j
2.When a const object is initialized from a compile-time constant, the compiler will usually replace uses of the variable with its corresponding value during compilation.
const int bufSize = 512; // the compiler will generate code using the value 512 in the places that our code uses bufSize.
3.To define a single instance of a const variable, we use the keyword extern on both its definition and declarations.
- By default, const objects are local to a file.
- When we define a const with the same name in multiple files, it is as if we had written definitions for separate variables in each files.
// file_1.cc defines and initializes a constthat is accesable to other files extern const in bufSize = fcn(); // file_1.h extern const in bufSize; // same bufSize as defined in file_1.cc
Initialization and References to const
1.We use a reference to const, which is a reference that refers to a const type.
Term: const Reference is a Reference to const
C++ programmers tend to abbreviate the phrase "reference to cosnt" as "const reference".
Technically speaking, there are no const reference. A reference is not an object, so we cannot make a reference itself const.
const in ci = 1024; const int &r1 = ci; // ok: both refernce and underlying object are const. r1 = 42; // error: r1 is a reference to const int &r2 = ci; // error: nonconst refernce to a const object
- Binding a reference to const to an object says nothing about whether the underlying object itself is const.
int i = 42 int &r1 = i; // r1 bound to i const int &r2 = i; // r2 also bound to i; but cannot be used to change i r1 = 0; // r2 is not const; i is now 0 r2 = 0; // error: r2 is a reference to const
2.With one exception of two, we can initialize a reference to const from any expression that can be converted to the type of the reference.
- We can bind a reference to const to a nonconst object, a literal, or a more general expression.
int i = 42; const int &r1 = i; // we can bind a const int& to a plain int object const int &r2 = 42; // ok: r1 is a reference to const const int &r3 = r1 * 2; // ok: r3 is reference to const int &r4 = r * 2; // error: r4 is a plain, nonconst reference
- We can bind a reference to const to an object of a different type.
double dval = 3.14; const int &ri = dval; // the compiler transforms this code into something like const int tem = dval; // create a temporary const int from the double const int &ri = temp; // bind ri to that temporary // If ri weren't const, we could assign to ri. // Doing so would change the object to which ri is bound. // That object is a temporary, not dval.
By default, a reference may be bound only to an object, not to a literal or to the result of a more general expressions.
The type of a reference and the object to which the reference refers must match exactly.
int &refVal4 = 10; // error: initializer must be an object double dval = 3.14; int &refVal5 = dval; // error: initializer must be an in object
Term: What is an Object?
In this book, we'll follow the more general usage that an object is a region of memory that has a type.
Pinters and const
1.Like a reference to const, a pointer to const says nothing about whether the object to which the pointer points is const.
Debuggign with reference to const and pointer to const
#include<iostream> using namespace std; int main() { int a = 4; const int& q1 = a; int& q2 = a; q1 = 10; // error: expression must be a modifiable lvalue. q2 = 10; const int* p1 = &a; int* p2 = &a; *p1 = 10; // error: expression must be a modifiable lvalue. *p2 = 10; cout << "q1 = " << q1 << endl; cout << "q2 = " << q2 << endl; cout << "p1 = " << *p1 << endl; cout << "p2 = " << *p2 << endl; // output: // q1 = 10 // q2 = 10 // p1 = 10 // p2 = 10 }
Pointers:
Unlike reference, a pointer is an object in its own right.
Pointers can be assigned and copied.
By default, the types of the pointer and the object to which it points must match.
double dval; double *pd = &dval; // ok: initializer is the address of a double double *pd2 = pd; // ok: initializer is a pointer to double int *pi = pd; // error: types of pi and pd differ pi = &dval; // error: assigning the address of a double to a pointer to int
2.Like any other const object, a const pointer must be initialized, and once initialized, its value( the address that it holds )may not be changed.
Top-level const
1.The distinction between top-level (the pointer itself is a const) and low-level (a pointer can poin to a const obj) matters when we copy an object.
int i = 0; int *const p1 = &i; // we can't change the value of p1; const is top-level const int ci = 42; // we can't change ci; const is top-level const int *p2 = &ci; // we can change p2; const is low-level const int *const p3 = p2; // right-most const is top-level, left-most is not const int &r = ci; // const in reference types is always low-level
- When we copy an object, top-level consts are ignored.
i = ci; // ok: copying the value of ci; top-level const in ci is ignored p2 = p3; // ok: pointed-to type matches; top-level const in p3 is ignored
- On the other hand, low-level const is never ignored. In general, we can convert a nonconst to const but not the other way round.
int *p = p3; // error: p3 has a low-level const but p doesn't int &r = ci; // error: can't bind an ordinary int& to a const int object p2 = p3; // ok: p2 has the same low-level cont qualification as p3 p2 = &i; // ok: we can convert int* to const int* const int &r2 = i; // ok: can bind const int& to plain int
Constexpr and Constant Expressions
1.A constant expression is an expression whose value cannot change and that can be evaluated at compile time.
- Constexpr variables
const int limit = max_files + 1; // limit is a constant expression const int sz = get_size(); // sz is not a contant expression (initialized at run time)
- Such expressions can be used as non-tpye template arguments, array sizes, and in other contexts that require constant expressions. (by "constant expressions" at cppreference.com)
int n = 1; std::array<int, n> a1; // error: n is not a constant expression const int cn = 2; std::array<int, cn> a2; // ok: cn is a constant expression
2.Literal types are the types of constexpr variables and they can be constructed, manipulated, and returned from constexpr functions. (by "Literal types" at cppreference.com)
3.Constexpr imposes a top-level const on the objects it defines.
const int *p = nullptr; // p is pointer to a const int constexpr int *q = nullptr; // q is a const pointer to int
这篇关于Const Qualifier的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享