Introduction to C++ Basics (Medium): Function Overloading, References, Inline Functions

Table of contents

introduction

1. Function overloading

1.1 Concept

1.2 Examples

① Different parameter types

② The number of parameters is different

③ The order of parameter types is different

Notice

1.3 Principle

for example

Notice

2. Citation

2.1 Referenced declarations and definitions

2.2 Characteristics of references

2.3 The difference between references and pointers

2.4 Common references

2.4.1 Frequently cited features

2.5 Reference application

3. Inline functions

3.1 How to declare an inline function

3.2 Advantages of Inline Functions

3.3 Considerations for Inline Functions


introduction

This series aims to provide beginners with a comprehensive and easy-to-understand C++ introductory guide . We will start with C++ keywords and gradually explore various aspects of C++, including namespaces, input and output, function features, and some new features of C++11auto , such as keywords, range-based for loops and nullptr. Each topic will have a concise explanation and sample code to help you better understand and apply this knowledge.

Whether you're just getting started with programming or want to switch to C++ from another programming language, this guide will help you build a solid foundation in C++. By studying this series, you will master the core concepts and common features of C++, laying a solid foundation for subsequent study and project development.

1. Function overloading

1.1 Concept

Function overloading is a very useful feature in C++ programming . It allows us to declare multiple functions with the same name in the same scope , but these functions have different parameter types or number of parameters or different order of parameters. Through function overloading, we can use the same function name to represent different operations, thereby improving the flexibility and readability of the code.

1.2 Examples

① Different parameter types

int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}


double Add(double left, double right)
{
    cout << "double Add(double left, double right)" << endl;
    return left + right;
}

② The number of parameters is different

void fun(int a)
{
    cout << "fun(int a)" << endl;
}

void fun()
{
    cout << "fun()" << endl;
}

③ The order of parameter types is different

void fun(int a, double b)
{
    cout << "fun(int a, double b)" << endl;
}

void fun(double a, int b)
{
    cout << "fun(double a, int b)" << endl;
}

When calling these functions, the user selects the function according to the requirements and passes in the actual parameters according to the function prototype , and the compiler will select the appropriate function to call according to the type and number of parameters passed to the function . In this way, we can use the same function name to represent different operations.

Notice

The validity of function overloading is distinguished according to the parameter list of the function, regardless of the return type . In C++, the return type of a function does not affect the selection process for function overloading. This is because the return type of the function is not used to resolve the ambiguity of function overloading when the function is called.

The overload solution of the function is that the compiler selects the correct function to call according to the type and number of parameters passed to the function. When the compiler calls a function, it will look for a matching function declaration based on the parameters actually passed. If a function declaration with a matching parameter list is found, the corresponding function is called, regardless of whether the return types of these functions are the same.

1.3 Principle

  1. Name Mangling (Name Mangling) : In C++, function overloading involves the distinction of function names. Since function overloading may have the same function name, in order to distinguish these functions during compilation, the C++ compiler will modify the function name, also known as name mangling (Name Mangling). Name mangling is the encoding of function name and parameter list information into a unique string, resulting in different function names after compilation. In this way, the same function name becomes different after compilation, so function overloading can be distinguished.

  2. Parameter matching : When making a function call, the C++ compiler will match the appropriate function according to the type and number of parameters passed. The compiler matches the actual and formal parameter types passed to the function to find a matching function declaration. Parameter matching is done at compile time, not run time.

  3. Function call resolution : Once the compiler matches a suitable function declaration, it generates the corresponding function call. Due to name mangling, the actual calling name of a function may not be exactly the same as the function name in the source code.

for example

int add(int a, int b);
float add(float a, float b);

The compiler may add(int, int)decorate the function name with "_Z3addii" and add(float, float)the function name with "_Z3addff" . Therefore, the function name called in the source code and the actual generated function name may be different

int sum1 = add(5, 10);          // 实际调用的函数名可能为"_Z3addii"
float sum2 = add(3.14f, 2.71f); // 实际调用的函数名可能为"_Z3addff"

Notice

The specific methods and rules of name decoration may be different in different compilers, which also leads to slight differences in how different compilers handle function overloading . In order to maintain backward compatibility, C++ provides extern "C"a mechanism for declaring C language function name decoration in C++ code.

2. Citation

In C++, references are a mechanism for aliasing variables . References allow us to access the value of an existing variable by its name, rather than creating a new storage space. References introduce a more intuitive and concise syntax to C++ and provide a safer and more efficient way to manipulate variables.

2.1 Referenced declarations and definitions

References are &declared using symbols. When declaring a reference, we must initialize it to the target of the reference, the variable to be referenced. Once a reference is initialized, it will always refer to that variable and cannot be rebinded to another variable .

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

int num = 10;
int& ref = num;  // 引用声明和初始化

The first line of code indicates that a space is opened in the space to store the value 10, and it is named num . The second line of code indicates that I give this space another name ref . Both names can operate on this space, and the effect is the same .

Note: The reference type must be of the same type as the referenced entity, of course there are exceptions, which will be explained later.

2.2 Characteristics of references

  1. Alias : A reference provides an alias for a variable. By reference, we can use different names to access the same variable.

  2. No null references : C++ requires that references must be initialized when they are declared, and once initialized, the object they refer to cannot be changed.

  3. No independent address : the reference itself does not take up memory space, it is just an alias for the variable. So the address cannot be obtained for the reference.

  4. Passing parameters : References are especially useful in function parameter passing. It can pass parameters by reference to realize the effect of modification of parameters inside the function on the original variables.

2.3 The difference between references and pointers

References and pointers are two different variable aliasing mechanisms in C++, with the following main differences between them:

  1. Initialization and rebinding : References must be initialized when declared, and once initialized cannot be rebinded to other variables. The pointer can not be initialized, and can be re-pointed to other variables.

  2. Null reference : C++ does not allow the creation of a null reference, that is, the reference must be bound to an existing object. However, pointers can point to nothing (nullptr).

  3. Syntax : References &are declared using symbols, and pointers *are declared using symbols.

  4. Memory occupation : The reference itself does not occupy additional memory space, while the pointer needs to store the address of the target object, occupying a certain amount of memory space.

2.4 Common references

A constant reference (const reference) is a special type of reference that is used in C++ to restrict modification of objects accessed through references. By declaring a reference as const, we tell the compiler that the object pointed to by the reference is read-only and that no modification of the object through the reference is allowed .

A constant reference is implemented by adding keywords to the reference declaration const, and its declaration form is:

const T& ref = 引用实体;
//T是要引用的对象类型

2.4.1 Frequently cited features

  1. Read-only access : With constant references, we can only read the value of the referenced object and cannot modify it. Any attempt to modify an object through a constant reference will result in a compilation error.

  2. Initialization requirements : Constant references must be initialized at the time of declaration, and can only refer to one variable or constant of the same type.

  3. Temporary object : A constant reference can be bound to a temporary object (rvalue), but since the temporary object will be destroyed after the expression ends, only the value of the temporary object can be accessed and cannot be modified.

   Example for the third point

int& ref = 10; //错误 10为右值,不能通过ref进行修改
const int& ref = 10; //正确 此时ref为常引用不可修改内容

2.5 Reference application

1. Function parameter passing : Passing parameters by reference can realize the modification of the original variable inside the function. Simplify the use of pointers.

void increment(int& x) {
    x++;
}

int num = 10;
increment(num);
// 现在num的值为11

2. Return value: The function can return the result by reference, avoiding the creation of temporary variables.

int& findLargest(int& a, int& b) {
    return (a > b) ? a : b;
}

int a = 10, b = 15;
int& largest = findLargest(a, b);
largest = 20;
// 现在b的值为20,即largest为b的引用

3. Avoid copying : References can avoid copying objects and improve code execution efficiency.

void processLargeObject(const LargeObject& obj) {
    // 处理大对象的操作,不需要复制对象
}

A constant reference is used here, which means that the object will not be modified within the function.

Notice

When returning the value in the second point, be careful not to return the temporary variable reference

int& fun()
{
    int a = 10;
    return a;
}

For example, in this code, the variable a will be destroyed immediately after the execution of the function. If it is still used as an alias according to the reference at this time, it is an illegal operation to cause uncertainty in the result.

3. Inline functions

Inline Function (Inline Function) is a function optimization mechanism in C++, which is used to insert the code of the function body directly into the calling site when the compiler is compiling, instead of executing it through a function call. Doing so can avoid the overhead of function calls and improve code execution efficiency.

3.1 How to declare an inline function

In C++, inlinea keyword is used to declare an inline function. Normally, you can use inlinethe keyword on member functions defined inside a class to declare them inline. For functions defined outside the class, you can use inlinekeywords at the function declaration and definition.

Inline functions defined inside a class:

class MyClass {
public:
    inline void myFunction() {
        // 函数体代码
    }
};

Inline functions defined outside the class

// 在函数声明处使用inline关键字
inline void myFunction();

// 在函数定义处使用inline关键字
inline void myFunction() {
    // 函数体代码
}

3.2 Advantages of Inline Functions

  1. Reduce function call overhead : When a function is called, the current execution state will be saved to the stack, then jump to the called function, and then return to the calling point after execution. This process involves the creation and destruction of multiple stack frames. The code of the inline function will be directly inserted into the call point, avoiding these additional overheads, thereby improving the execution efficiency of the code.

  2. Save memory space : The code of the inline function will be directly inserted into each call point, and no copy of the function will be generated in memory, thus saving code space.

3.3 Considerations for Inline Functions

  1. The complexity of inline functions : Inline functions are usually suitable for short functions , because the function body is too complex to cause code bloat, which will reduce performance. Compilers may reject inlining of complex functions that are inlined .

  2. Compiler decision : The use of keywords is just a suggestioninline to the compiler for inlining , and it is ultimately up to the compiler to decide whether to use the function as an inline function. The compiler may ignore keywords, especially for overly complex or recursive functions.inline

  3. Inline does not recommend separation of declaration and definition, which will lead to link errors.

  4. Avoid abuse of inline functions : Although inline functions can bring performance benefits, not all functions are suitable for inlining. The code of an inline function will be copied to each call site. If the function body is too large or called frequently, it will cause code bloat, which may degrade performance instead.

Guess you like

Origin blog.csdn.net/weixin_57082854/article/details/132069044