[C++] Function overloading, references, inline functions.

Table of Contents

1. The concept of function overloading

Specific implementation examples

Functions with the same name have different numbers of parameters

Functions with the same name have different parameter types

Parameter types of functions with the same name are in different order

Why C++ supports function overloading

Replenish:

2. Quote

Quoting concepts:

Specific usage:

Practical application scenarios:

Scenario 1: Making parameters

Scenario 2: Making return values

Often quoted

Replenish:

3. Inline functions


1. The concept of function overloading

Function overloading: It is a special case of functions. C++ allowsdeclaration of severalsimilar functions in thesame scope > Functions with the same name. These functions with the same name have different formal parameter lists (number of parameters or types or type order). They are often used to handle different data types that implement similar functions. The problem.

Note: C language does not support function overloading.

Specific implementation example

The number of parameters of functions with the same name is different

#include<iostream>

using namespace std;


int Add(int x, int y) {

return x + y;
}

int Add(int x, int y, int z) {

return x + y + z;
}


int main() {

//The number of parameters of the function with the same name is different
int x = Add(1, 2);
int y = Add(1, 2, 3);

cout << "x = " << x << endl;
cout << "y = " << y << endl;

return 0;
}

Output results:

The parameter types of functions with the same name are different

#include<iostream>

using namespace std;


int Add(int x, int y) {

return x + y;
}

double Add(double x, double y) {

return x + y ;
}


int main() {

//The parameter types of functions with the same name are different
int x = Add(1, 2);
double y = Add(1.2,1.2);

cout << "x = " << x << endl;
cout << "y = " << y << endl;

return 0;
}

Output results:

The order of parameter types of functions with the same name is different

#include<iostream>

using namespace std;


int Add(int x, double y) {

return x + y;
}

double Add(double x, int y) {

return x + y ;
}


int main() {

//The parameter types of functions with the same name are different
int x = Add(12.2, 2);
double y = Add(1.2,1);

cout << "x = " << x << endl;
cout << "y = " << y << endl;

return 0;
}

Output results:

The reason why C++ supports function overloading

Mainly because in C++ syntax, the compiler will modify the function name during compilation.

The C language does not modify its function name, so C does not support overloading.

As follows:

//Under the gcc compiler, the compiler’s rules for modifying function names are roughly as follows:
//_Z3Adddi
//Among them, _Z is a fixed prefix, Add is the function name, and the last two d i refer to the first letter of the function parameter type.
double Add(double x, int y) {

return x + y ;
}

In this way, you can simply understand why C++ supports overloading, and understand why the formal parameter lists (number of parameters or types or type order) of functions with the same name should be different . In this way, after the function name is modified by the compiler, it can be used as a different function.

Supplement:

If the function names and parameters of two functions are the same and the return values are different, it does not constitute overloading.

2. Quote

Quoting concept:

A reference is not a newly defined variable, but an alias for an existing variable. The compiler will not allocate memory space for the reference variable. It is shared with the variable it refers to. the same memory space.

For example, in the Chinese comic “Under One Man”, the character Wang Ye has a nickname called Mr. Ye, and a closer personis called Xiao Wangye.

Ye always refers to the person Wang Ye. Wang Ye can be Ye Zong, and Xiao Wang can also be Wang Ye or Ye Zong.

In short, they all refer to the same person.

So, to put it simply, quoting is equivalent to giving a variable a nickname in real life.

Features:

1. References must be initialized when defined

2. A variable can have multiple references

3. Once a reference refers to an entity, it can no longer refer to other entities

Specific usage:

Type & reference variable name (object name) = reference entity;

int x = 0;

int & y = x;

In this way, y can be regarded as x, sharing the same memory space.

Actual application scenario:

Scenario 1: Making parameters

Mainly output parameters, changes in formal parameters affect actual parameters.

Scene import:

If we want to use a function to swap the positions of two numbers, how would you write the code?

Is that so?

void Swap(int x, int y) {

int tmp = x;
x = y;
y = tmp;
}

int main() {

int x = 3;
int y = 5;

Swap(x, y);//Function to swap the positions of two numbers

cout <<"x = " << x << endl;
cout <<"y = " << y << endl;

return 0;
}

The running results are as follows:

Above we found that its function did not work at all and its data was not exchanged at all.

So why is this?

This is because in a function call, the formal parameter is only a temporary copy of the actual parameter, and changes to the formal parameter or related operations will not affect the actual parameter.

So how would you do it in C language?

As follows:

The C language adopts the pointer method to solve the problem, and realizes the exchange function function by dereferencing the pointer.

So how does C++ solve it?

It is more convenient to use references to solve this problem, which is more convenient than using pointers.

When calling a parameter, just reference it. In this way, the formal parameter and the actual parameter can be regarded as the same variable. Therefore, when the Swap function is called, the change to the formal parameter also changes the actual parameter. The parameters have been changed.

Note: Reference type and Reference entity must be of the same type.

Scenario 2: Making a return value

1. Return by value (used when the function returns, the return object has been returned to the system)

Here the n variable has been returned to the system.

2. Return by reference (used when the function returns, the return object has not been returned to the system. Such as: static, global, upper layer stack frame, malloc, etc.)

The n variable here is in the static area and has not been returned to the system.

Mistake 1:

The above code fails to compile.

This is because the Count() function returns a newly created temporary variable, which is a copy of the n variable, but with the same value. And the temporary variable will be defined as const type, so it cannot be modified.

The solution is to return a reference to variable n.

That is written as:

const int & amp; ret = Count();

Extras:

The main reason why the temporary variable here will be defined as const type is that when performing type conversion, a temporary variable will be generated, that is, a copy of the variable needs to be converted, but their values are equal, and the temporary variable will be defined as const type, so it cannot be modified and is equivalent to a constant variable.

Example:

int i = 0;

double & amp; di = i;//Compilation failed. Type conversion is done here.

const double & amp; di = i; //Compilation passed

Mistake 2:

int & amp; Mul(int a, int b) {
int c = a * b;
return c;
}

int main() {
int & amp; ret = Mul(1, 2);
Mul(3, 4);

cout << "Mul(1,2) is:" << ret << endl;
cout << "Mul(3,4)is:" << ret << endl;
return 0;
}

Output results:

If c in Mul function is not modified with static, it will be destroyed together after the call of Mul function is completed. So you cannot use reference return, you have to use value return.

(Destruction here means that you no longer have the right to use this space. After the system reclaims this space, it may store other data, or it may continue to temporarily store n’s data.)

So if you continue to use pass-by-reference return at this time, the return result will be unknown.

Practical application of return by reference:

#define N 10//Define the length of the array

typedef struct Array {

int a[N];

int size;
}Array;

//Return by reference
//1. Reduce copying
//2. The caller can modify the returned object

int & amp; PosAt(Array & amp; arr, int i) {
assert(i < N);
\t
return arr.a[i];

}

int main() {

Array arr;
for (int i = 0; i < N; i + + ) {

PosAt(arr, i) = i * 10;//Modify the returned object

cout << arr.a[i] << endl;
}

return 0;
}

often cited

Cannot reference constant

int main() {


const int a = 10;
int & amp; ra = a;//An error will be reported here

return 0;
}

Additional:

Supplement 1:

typedef struct Node{

struct Node* next;
int val;

}Node,*PNode;//Give the Node structure two aliases, Node and its pointer name *PNode

void PushBack(PNode & amp; phead, int x) {//The PNode & amp; here refers to the alias of Node* and the reference to it
Node* newNode = (Node*)malloc(sizeof(Node));
\t
if (phead == NULL) {

phead = newNode;

}
}

Supplement 2:

When assigning or initializing pointers and references, the permissions can be reduced, but cannot be enlarged.

Note: This premise is only true when using pointers or references.

int main() {

//Permission amplification
const int a = 2;//Read only and cannot write
int & amp; b = c;//Readable and writable, compilation fails
\t
const int* pi = NULL; //Read only and cannot write
int* p2 = pi;//readable and writable, compilation failed

//Permissions maintained
const int d = 1;//Read only and cannot write
const int & amp; e = d; //Read only but not write

const int* pj = NULL; //Read only and cannot write
const int* p2 = pj;//Read only but not write

//Narrow permissions
int f = 2; //readable and writable
const int g = f; //Read only but not write

int* pk = NULL;//readable and writable
const int* p3 = pk;//Read only but not write




return 0;
}

The difference between references and pointers:
1. Reference conceptually defines an alias of a variable, and a pointer stores a variable address.
2. References must be initialized when defined, and there are no requirements for pointers.
3. After a reference refers to an entity during initialization, it can no longer refer to other entities, and a pointer can point to any entity of the same type at any time.
4. There is no NULL reference, but there is a NULL pointer
5. The meaning in sizeof is different: the reference result is the size of the reference type, but the pointer is always the number of bytes occupied by the address space (4 bytes on a 32-bit platform)
6. The reference is self-increasing, that is, the referenced entity is increased by 1, and the pointer is self-increasing, that is, the pointer is offset backward by the size of the type.
7. There are multi-level pointers, but no multi-level references
8. The way to access entities is different. The pointer needs to be explicitly dereferenced, and the reference compiler handles it by itself.
9. References are relatively safer to use than pointers

3. Inline function

Definition:

Functions modified with inline are called inline functions. When compiling, the C++ compiler will expand the inline function where it is called. There is no overhead of establishing a stack frame for function calls. Inline functions improve the efficiency of program operation.

Exchanging time for space when inline refers to the space during compilation, and inline may not necessarily be called, it is just a suggestion to the compiler. It may be called during compilation, that is, skipped.

//C++ recommended
//const and enum replace macro constants
//inline to replace the macro function
//
//
//Macro disadvantages:
//1. Cannot debug
//2. No type safety check
//3. Some scenarios are very complex, error-prone, and difficult to master.
//
//
//Required to implement the ADD macro function
#define Add(x,y) ((x) + (y))

inline int Add1(int x, int y) {

int z = x + y;
return z;

}

int main() {

//Question 1: Add (x, y) (x) + (y) Is it possible without the outer braces? no
//As follows, if no outer braces are added, it will become (1) + (2) * 3.
//And originally you wanted 1 + 2 and times 3. But since multiplication has higher priority than addition it now becomes 1 + (2 * 3)
Add(1, 2) * 3;



//Question 2: Is it possible to omit the braces in Add(x,y) (x + y)? no
//Because macros are directly replaced violently
//So when the following program does not add the braces inside,
//When calling the macro function, it will become (x & y + x | y).
//And you originally wanted the results of x & y to be added to the results of x|y.
int x = 1, y = 2;
Add(x & y, x | y);


//Replace with inline functions
int ret = Add1(1, 2);
cout << ret << endl;


return 0;
}

Note: The declaration and definition of inline functions should be together, not separately. Otherwise a link error will occur.

If the function is only declared in the .h file, the function is defined in the .cpp file. Then when the main function entry calls this function, it will only include the following .h file. As a result, the definition of the corresponding function is not found during the compilation stage, which will result in a link error!