[C++ Primer Plus] Study Notes-Chapter 8 Function Exploration


8.1 C++ inline functions

P253

The execution process of regular function calls and inline functions

The final product of the compilation process isExecutable program-Consists of a set of machine languages. When running the program, the operating system loads these instructions into the computer memory, so each instruction has a specificMemory address. The computer will then gradually execute these instructions. Sometimes (such as when there is a loop or branch statement), some instructions will be skipped, forward or backwardJump to the specified addressRegular function callIt also makes the program jump to another address (the address of the function) and return when the execution ends. The typical implementation of this process is described in more detail below.

When the function call instruction is executed, the program will immediately after the function callstorageOf the instructionMemory addressAnd willCopy function parameters to the stack(Memory block reserved for this), jump to the mark functionMemory unit, Execute the function code (maybe you need to put the return value in the register), and then jump back to the instruction where the address is saved. Jumping back and forth and recording the jump position means that when using the function before, a certain amount ofOverhead

C++Inline functionProvides another option. The compiled code of the inline function is "inlined" with other program code. In other words,The compiler will replace the function call with the corresponding function code. For inline code, the program does not need to jump to another location to execute the code and then jump back. Therefore, the inline functionRunning speedThan regular functionSlightly faster, But the price is needTake up more memory. If the program calls the same inline function in 10 different places, the program will contain 10 of the codeCopy. in caseVery short code execution time, Then inline calls can save most of the time used by non-inline calls.

Inline functionwithRegular functionCall diagram
Insert picture description here

Inlining and Macro

Inline functions are the same as regular functions, pressPass-by-value parametersof. The macro function simply passesText replacementto realise.

Technique : UseC++ inline functioninsteadMacro definition

code show as below:

// a inline function definition
inline double square(double x){
    
    return x*x;}

#define SQUARE(X) X*X

a = square(4.5 + 7.5); // is replaced by (4.5+7.5)^2
b = SQUARE(4.5 + 7.5); // is replaced by 4.5 + 7.5*4.5 + 7.5

8.2 Reference variables (emphasis)

P255

The main purpose of reference variables is to be used asFunction parameter.
Must be done when declaring reference variablesinitialization. Quotes closer toconst pointer.
C++ references can be achieved compared to pointersOperator overloading

int &rodents = rats;
// 伪装表示如下,const变量必须初始化
int* const pr = &rats; 
//引用 rodent 等价于 *pr

Functions passed by value can use multiple types of actual parameters;Passed reference restrictions are stricterNon-constant referenceThe argument should beLeft value

Left value

  • Left value (Can be accessed by address) The parameter can beQuoteThe data object. For example: variables, array elements, structure members, reference and dereference pointers are all lvalues.
  • Non-lvalue (No specific address) Includes literal constants (except for character strings enclosed in quotation marks) and expressions containing multiple items.

const reference

in caseActual participation reference parameter does not match, Only if the parameter isconst referenceWhen, C++ will generateTemporary anonymous variables

Compared to value passing,const referenceCan reduce the cost of copying actual parameters to formal parameters.

If the purpose of the reference parameter as an actual parameter is to modify the variable passed as a parameter, thenProhibit the creation of temporary variables. Instead, the purpose is to use the passed values ​​without modifying them, and should be declared asconst reference.
code show as below:

double cube(double a);
double refcube1(double &ra);
double refcube2(const double &ra){
    
    return ra*ra*ra};
//...
double z = cube(x + 2.0); //evaluate x+2.0, pass value
double z = refcube1(x + 2.0); //no, should not compile
double z = refcube2(x + 2.0); //yes, ra is temporary variable

Skills :Use const references whenever possible

  • const references can avoid programming errors that accidentally modify data.
  • Const references enable functions to handle const and non-const arguments.
  • The const reference enables the function to correctly generate and use temporary variables.

Return reference

int& reftarget(int& rt) {
    
    
rt +=rt;
return rt;
}
//...
int target1 = 10;
int target2 = reftarget(target1);

If ref returns int instead of pointing to a reference, you need to copy rt to a temporary variable, and then copy this copy to target2. If ref returns an int reference, copy rt directly to target2 ,higher efficiency

Note】:Cannot return a reference to a temporary variable, it will be destroyed after the function runs

// 返回const引用,creftarget变为不可修改的左值
const int& creftarget(int& rt);
creftarget = 4; //not allowed for const reference return

Skills :When you need to return a reference, but don't want it as an lvalue. Can return a const reference, can avoid the return value as an lvalue, and avoid ambiguity

When to use reference parameters

For functions that use values ​​without modifying the value

  • Built-in data type, pass by value
  • Array, you can only use pointers
  • For larger structures, use pointers or references
  • Class object, use reference

For built-in data types , the number of bytes of data is small (32-bit pointer 4 bytes), andPass by valueFor direct addressing, the efficiency is higher.
When an array is used as an actual parameter, you only need to pass the first address of the array to the function, and the function will use the original function.Pointer passing.
For class objects , the semantics of class design often requires the use of references; at the same time, reference passing has parameter checking, which is safer than pointer passing; the standard way to pass class object parameters isPass by reference

8.3 Default parameters

P274

byFunction prototypeSet the default parameters, the formal parameters must be fromRight to leftAdd default values.

void harpo(int n, int m = 4, int j = 5); //valid
void chico(int n, int m = 6, int j); //invalid

Argument by theLeft to rightThe sequence of is assigned to the corresponding formal parameters, and no parameters can be skipped.

harpo(2); // same as harpo(2, 4, 5)
harpo(1, 8); // same as harpo(1, 8, 5)

When designing a class, by using default parameters , you can reduce the number of destructors, methods, and method overloads to be defined.

The default parameter codes are as follows:

//left.cpp -- string function with a default argument
#include<iostream>
const int ArSize{
    
     80 };
char* left(char* str, int n = 1); //function prototype

int main()
{
    
    
	using namespace std;
	char sample[ArSize]{
    
    };
	
	cout << "Enter a string: ";
	cin.get(sample, ArSize);
	char* pr = left(sample, 10);
	cout << pr << endl;
	delete[] pr;
	pr = left(sample);
	cout << pr << endl;
	delete[] pr;

	system("pause");
	return 0;
}

//consisting of the first n characters in the str string
char* left(char* str, int n)
{
    
    
	if (n < 0)
		n = 0;
	char* p = new char[n + 1]{
    
    };
	int i{
    
    };
	for (; i < n && str[i]; i++)
		p[i] = str[i];
	while (i<=n)
	{
    
    
		p[i++] = '\0';
	}
	return p;
}

8.4 Function overloading

P296

The key to function overloading is to elaborateDifferent signatures, That is, the number of parameters or parameter types are different .

Reference overloading

The compiler will putType referencewithType itselfTreated as the same signature, their argument types are the same, so no overloading occurs. It is worth noting:Function overloading occurs when frequently quoted

double cube(double x); // not overloaded
double cube(double& x); // not oberloaded
//... 
//const reference
double cube(double& x); // overloaded
double cube(const double& x); // oberloaded

const overload

The following two functions areredefine, It is not a function overloading. Both functions will not change the value of a. They are essentially the same, so an error will be reported, prompting the function to be redefined.

void func(int len);  //not overloaded
void func(const int len); //not overloaded
//...
func(a);

For the following two functions will be overloaded, the first function is usedRegular pointer, Another function forconst pointer, The compiler will decide which prototype to use based on whether the actual parameter is const.

void func(char* str);  //overloaded
void func(const char* str); //overloaded
//...
func(p1);

Different return types

[Note]: YesDifferent signatures, Not the function type.

long gronk(int n); // same signatures,
double gronk(int n); // not overloaded

Therefore, the return type can be different, but mustDifferent signaturesFunction overloading can occur.

long gronk(int n); // overloaded
double gronk(double n); // overloaded

8.5 Function template

If you need multiple uses of the same algorithm for different types of functions, use function templates .

//function template prototype
template <typename/class T>  
void Swap(T& a, T& b);
//标准C++98,添加关键字typename

note:Function templates cannot shorten executable programs. The final code does not contain any templates, but only the actual functions generated for the program.

The advantage of the function template is: it makes the generationMultiple functionsThe definition is simpler and more reliable.

Explicit reification

Template functions may not be able to handle certain data types (such as structures). So one solution is operator overloading, the otherProvide specific template function definitions for specific types

The explicit reification is as follows:

template<> void Swap<job>(job &, job &);
template<> void Swap(job &, job &); // <job>可以省略

Instantiation and reification

Templates are not function definitions, but template instances using int are function definitions- implicit instantiation

The explicit instantiation is as follows:

template void Swap<job>(job &, job &);

Using the same type of display instance and explicit reification in the same file will cause errors .

Show instantiation, Regardless of whether the program is useful or not, the compiler will generate an example function.

Call priority : non-template function> explicit reification> explicit instantiation> template function

Keyword decltype (C++11)

Role: select and return the data type of the operand

int x;
decltype(x) y; //make y the same type as x

C++ post return type

template <typename T1, typename T2>
auto gt(T1 x, T2 y) ->decltype(x + y) // 后置返回类型
{
    
    
	//...
	return x + y;
}

Guess you like

Origin blog.csdn.net/ZR_YHY/article/details/111637904