Inline functions and references < introduction to C + + (runner's notes)

quote

Concept:

Instead of defining a new variable, a reference gives an alias to an existing variable. The compiler will not open up memory space for the referenced variable. It shares the same memory space with the variable it references.

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

For example, if a person names a temporarily used shaping variable as o, you can refer to o by reference and replace it with tmp

int& tmp = o; that will do

So we can use tmp as an alias of o

Reference properties

  1. A variable can have multiple references
  2. Reference once an entity is referenced, other entities cannot be referenced
  3. It's worth saying that although we quote the surface value, in fact, we are really passing the address
  4. References must be initialized when defined

Reference constant

When referencing mismatched types:

What happens if you use the int type to reference double?

Direct reference is no good

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-h1NvtSJB-1652361941334)(... /... / appdata / roaming / typora / typora user images / image-20220511160334042. PNG)]

Add const and go through the conversion

When we apply this to function parameters, we can efficiently receive any type

Of course, for such references, we only have read permission and cannot write

Why can we join const to receive it?

This is related to the conversion process of our compiler

When converting, our compiler will first create a space to accept the accepted value, as shown in the figure above is a, and then change it before giving us the received value (ra in this example). Therefore, the value received by ra is actually a constant, so it should be decorated with const

Take a look at the screenshot of the ra address:

Although a is referenced, the addresses of ra and a are different, and the address of ra is actually the address of constant 10

Usage scenario

1. Make parameters

2. Return value

Of course, this lecture will not really play a follow-up role

Comparison of efficiency of value transfer and reference transfer

#include<iostream>
#include <time.h>
using namespace std;
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{
	A a;
	// Take value as function parameter
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// Take reference as function parameter
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// Calculate the time after the two functions run respectively
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
	TestRefAndValue();
	return 0;

}

The results are as follows:

Pass reference after explosion

Efficiency comparison between return reference and return value

#include<iostream>
#include <time.h>
using namespace std;
struct A { int a[10000]; };
A a;
// Value return
A TestFunc1() { return a; }
// Reference return
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{
	// Take value as the return value type of function
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	// Take reference as the return value type of function
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	// Calculate the time after the operation of two functions is completed
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

int main()
{
	TestReturnByRefOrValue();
	return 0;
}

The difference between reference and pointer

Syntactically, a reference is an alias. There is no independent space, and it shares the same space with its reference entity. However, there is space in the underlying implementation, because references are implemented in the form of pointers.

Let's see if there is a significant difference between pointer and referenced assembly code

int main()
{
	int a = 10;
	int& ra = a;
	ra = 20;
	int* pa = &a;
	*pa = 20;
	return 0;
}

The difference between pointer and reference

  1. References must be initialized when defined, and pointers are not required
  2. After a reference references an entity during initialization, it can no longer reference other entities, and the pointer can point to any entity of the same type at any time
  3. There is no NULL reference, but there is a NULL pointer
  4. In sizeof, the meaning is different: the reference result is the size of the reference type, but the pointer is always the number of bytes in the address space (4 bytes in 32-bit platform)
  5. Reference self addition means that the referenced entity increases by 1, and pointer self addition means that the pointer is offset by one type backward
  6. There are multi-level pointers, but there are no multi-level references
  7. The access to entities is different. The pointer needs to be explicitly dereferenced, and the reference compiler handles it by itself
  8. References are relatively safer to use than pointers

Inline function

concept

When the compiler calls inline functions, it will improve the efficiency of C + + functions that are not inline.

Let's turn the Swap() function we often use into an inline function

If it's not an inline function, let's look at the assembly code. You can see the call instruction and then press the function stack

However, the function assembly code modified by inline will not have call and other instructions Take a look at the picture above

Undecorated:

After modification:

However, in the debug mode, you need to modify the function of inline

VS2022 can be seen through the following method

After modification, you can see the disassembly by yourself

characteristic

  1. Inline is a method of exchanging space for time, which saves the cost of calling functions. Therefore, functions with long code or loop / recursion are not suitable for inline functions
  2. Inline is only a suggestion for the compiler. The compiler will optimize automatically. If there are loops / recursions in the function defined as inline, the compiler will ignore inline during optimization
  3. Inline does not recommend the separation of declaration and definition, which will lead to link errors. Because the inline is expanded, there will be no function address, and the link will not be found

Tags: C++ programming language

Posted by 051119 on Thu, 12 May 2022 23:38:17 +0300