Pay attention to this point
- Const object defaults to a local variable of the file
When defining a non-const variable in the global scope , it can be accessed throughout the program, and we can define a non-const variable in a file, assuming that the appropriate declaration has been made, and that the variable can be used in another file:
Unlike other variables, a const variable declared at the global scope is a local variable of the file that defines the object, unless otherwise noted. This variable exists only in that file and cannot be accessed by another file . By specifying the const variable as extern, you can access the const object throughout the program.
Note: The non-const variable defaults to extern. In order for a const variable to be accessible in another file, it must be explicitly specified as extern in the file.
-------------a const pointer, const reference, const reference parameter--------------------
"1" const modifier pointers and references
1. The term "Const reference" is "a reference to a const object", which is customary to say a const reference to a non-const reference. Unlike pointers, the "const pointer" in the pointer is different from the pointer to a const object.
2. It is worth noting that both const references and pointers to const objects have one thing in common: a const reference can point to a const object and to a non-const object, as well as a pointer to a const object.
3. For a const pointer and a pointer to a const object, give a very simple example
123456 |
int m=1, n=5;
const
int
*p1=&m;
//指向const对象的指针:const修饰的是*p1, 即*p1的值是只读的;但是p1这个指针是可以修改的。
int *
const p2=&n;
//const指针:const修饰的是p2, 即p2这个指针是只读的;但是*p2的值是可以修改的。
p1=&n;
//p1的指针修改为变量n的地址,而这个地址就是p2,相当于p1=p2;
*p2=3;
//*p2的值修改为3,当然*p1的值也就是3
printf
(
"%d %d\n"
,*p1,*p2);
|
The benefit of the "2" parameter as a const reference
When it comes to Const, we have to mention the formal parameters of the const reference type and really understand the benefits of the const reference parameter, only to find that it is really wonderful
A brief summary, welcome to add
A. When the type of the argument is large, the replication overhead is large (when the parameter is initialized) and the reference "avoids copying." (This is more commonly used when passing class objects)
B. "Avoid modifying arguments", when using references, if the caller wants to use only the arguments and does not modify the arguments, the const avoids using the reference to modify the argument
C. More practical than non-const reference parameters: Formal parameters can be initialized with a const object and can be initialized with the literal or rvalue expression arguments.
Each of the following gives an example
12345678 |
a.
void
search(
const
vector<
int
> & vec) 避免了实参的复制开销
b. 同a例,可避免对实参做出修改
c. 如下函数,调用时
void search(string & s); 调用: search(
"hello"
);
// Error 实参为字面值常量
void search(
const string & s); 调用: search(
"hello"
);
// OK
再如
void search(
int & v); 调用: search(v1+v2);
// Error 实参是一个右值,无法给引用赋值(需要左值)
void search(
const int & v); 调用: search(v1+v2);
// OK
|
---------------Const----------------------------------------in the class
In general, using the const modifier function, the function must be a class member function.
The "1" Const object can call the const member function only if the const member function is not a const object
Explanation: A pointer to a const object cannot be assigned to a non-const object pointer, and a non-const object pointer is allowed to be assigned to a pointer to a const object.
Why do you explain that? This originates from what happens when the member function is called:
What happens when a member function is called: Binds the calling object to the function, initializes the parameter this implied by the member function to the address of the calling object.
Therefore, the Const object passes the argument address as const class * const This, and not when the const member function is called or when the parameter of class *const this is used to receive, the result is a pointer to the const object that is assigned to the non-const object , this is not allowed, so the const object can only invoke the const member function, which, in the same vein, the non-const object, when calling the Const member function, essentially assigns a pointer (argument) of a non-const object to the Const object pointer (formal parameter), which is also possible, Therefore, a const member function can be called by a non-const object.
The "2" Const member variable cannot be modified and must be assigned to a value in the initialization list;
The const member function cannot change member variables and cannot invoke non-const member functions (that is, attempts to change values)
Conversely, non-const member functions can of course call the const member function
return value for "3" Const member function: value type & Const reference type (non-const reference not returned)
1234567891011 |
example.
class
Vec
{
private
:
vector<string> textVec;
public
:
const
string & text_line(
size_t
lineNum)
const
{
return
textVec.at(lineNum-1);
}
};
|
If the member function is const, the object calls the constant function passing this when it has become a const object, if the function is written as follows
1234 |
string & text_line( size_t lineNum) const { return textVec.at(lineNum-1); } |
Compile error: Cannot convert const string to string &, because this is equivalent to pointing a non-const reference to a const type variable. Therefore, to return a reference, it must be a const reference.
------------The return value type---
There are, of course, other ways to make the return value of a function a value type, which is
1234 |
string text_line( size_t lineNum) const { return textVec.at(lineNum-1); } |
This is actually a memory copy, because string is a class type, and one would ask, is that not equivalent to assigning a const object to a non-const object?
For the above function, it is actually called the copy construction of the string, and the copy construction parameter is the const string type, here is also related to the const type as a parameter, the above is said
The return value of a function is a value type, there are two types, one is the normal built-in type, the assignment operation, and the other is the class type, which is called copy construction for memory copy. As follows:
1234 |
const int a = 9; int b = a; ( int &bb = a; // error) // 赋值 const set< int > s; set< int > ss = s; // 内存拷贝 |
So we should pay attention to:
You cannot assign a const object pointer or reference to a pointer and reference to a non-const object, but you can initialize a const object to a non-const object;
The reciprocal assignment of const and non-const at the object level (not reference or pointer level) is permissible, reversible; just like
123 |
const int a = 9; int aa = a; const int aaa = aa; |
-------------------Const and Overloaded---------------------------------------
There are two types of const overloads, one based on whether the function parameter type is const, and one that is based on whether the class member function is a const overload
"1" is an overload based on whether the function parameter type is const
Whether the formal parameter is const is affected if and only if the parameter is a reference or pointer type
-----Reference type----
You can implement overloading on a function-based reference parameter that points to a const object or to a non-const object, as shown in the following example:
123456 |
A: void search(Student &); B: void search( const Student &); const Student a; Student b; search(a); // 调用B search(b); // 调用A |
Note: As we know from the above, if the formal parameter is a normal reference, you cannot pass the const object to the parameter.
If you are passing a non-const object, as mentioned above, both functions are feasible because non-const objects can be used either to initialize a const reference or to initialize a non-const reference. So there's no ambiguity?
This is the principle that the compiler follows when calling a function, first of all, "exact match," and we know that the const reference is initialized to a non-const object that requires an implicit conversion, so it does not conform to exact match, so call a.
-----pointer type----
A const overload based on a pointer parameter is the same as a reference. Just have one question to note:
The above term says that a const reference is a reference to a const object, which is distinguished from a const pointer and a pointer to a const object.
So note: You cannot overload a function based on whether the pointer itself is const
1234 |
void search( int * ptr); void search( int * const ptr); // 这不能实现重载,指针本身是否const并不会带来区别 // 在函数调用时,形参都复制了指针的值 |
"2" is an overload based on whether the class member function is const
In a class, a member function can be overloaded based on whether the member function is const, as follows
1234567891011121314 |
class
Vec
{
private
:
vector<string> textVec;
public
:
const
string & text_line(
size_t
lineNum)
const
{
return
textVec.at(lineNum-1);
}
string & text_line(
size_t
lineNum)
{
return
textVec.at(lineNum-1);
}
};
|