C++函数(进阶)

一 内联函数:
     与一般函数相比,编码的方式相同,不同的地方在于函数的调用机制。
     这是C++为了提高函数的运行效率所创建。
     内联函数的声明: inline 返回值类型 函数名(参数列表)。
     其运行的机制就是在于,当调用内联函数时,直接将函数的代码复制到调用的函数的地方
     这个方法适合小型函数的使用,否则大型函数的直接复制,将很浪费时间和资源。

此处C++的内联函数类似于C语言中的宏定义的功能,如:
    #define N 6 相当于在以后使用 N 时,都会自动替换成 6
    #define sum(num)  num + num 相当于以后再调用 sum(num) 时,等于调用 num + num 
   

  如图,内联函数的声明和调用方法如下所示:  

 

 

 

内联函数的定义方法:  在函数声明是加 inline, 或者是在函数实现时加 inline

 

 

二  reference 引用 相当于为对象起了一个别名
    int value = 99;
    int& refvalue = value; refvalue指向value是其另一个名字,所以以后操作refvalue的时候,等于操作value

    注意:定义引用的时候,必须进行初始化,不可以直接引用常量
         错误:int& refvalue = 5; 
    如果想要引用常量,可以定义为:
         const int& refvalue = 6;

    当使用引用变量时,相当于直接使用原始数据,而不是副本,相当于 const 指针
    
引用和指针的使用实例:

    # include <iostream>
    using namespace std;
    
    void Swap1(int&, int&);
    void Swap2(int*, int*);
    int main()
    {
        int num1  = 5, int num2 = 50;
        Swap1(&num1, &num2);
        Swap2(num1, num2);
        return 0;
    }

    void Swap1(int& num1, int& num2)  使用引用来作为参数进行交换
    {
        int temp;
        temp = num1;
        num1 = num2;
        num2 = temp;

        return;
    }
    void Swap2(int* num1, int* num2)  使用指针作为参数进行交换
    {
        int temp;
        temp = *num1;
        *num1 = *num2;
        *num2 = *num1;

        return; 
    }


    使用引用的好处:1 可以更加简便的书写代码  2 直接传递对象, 而不是复制一个副本 
三  函数的返回值是引用类型

    1. 不要返回局部变量的引用,因为变量有自己的生存周期,
       当函数结束时,函数内部声明的变量就会被回收。所谓的内存回收,并不是销毁内存中原有的数据,
       而是指,这块内存不在归本函数使用,其他的函数可以对这块内存进行修改,
       就像,租房子的时间到了,要把房子进行归还,新住进来的人将会改变房子中的内容。

    2. 函数可以没有返回值 当函数返回为引用类型是,必须是参数列表中的某个参数,
       假设函数的声明: int &sum(int& num1, int& num2) 
       不能返回        return num1 + num2; 只能返回 num1 或者是 num2
    
    3. 如果定义的函数返回类型为引用类型, 为了保险,要在函数的声明部分加 const
       const int& sun(int&, int&); 防止出现 sum(num1, num2) = 88; 这样的模糊定义 
       
    #include <iostream>
    #include "reference.hpp"
    using namespace std;

    int &sum(int&, int&);

    int main()
    {
        int num1 = 5, num2 = 10;
        int& result = sum(num1, num2);
        cout << "result = " << result << endl;

        return 0;
    }

    int &sum(int& num1, int& num2)  当函数没有设置返回值的时候,默认返回最后一个变量的引用
    {
        num1 = 5;
        num2 = 6;  可以没有返回值
    }
四. 按值传递、按指针传递和按引用传递,在函数使用方面三者怎么选择。
    
    1. 使用引用传递的时候,可以修改对象的内容
    2. 数据对象较大时,传递引用可以增加效率
    3. 当函数中不需要进行对象内容的修改时
        如果数据对象很小,则建议按值进行传递
        传递数组的时候,只能用指针传递
        数据对象很大时,建议使用 const 指针或引用 以提高运行的效率
    4. 需要修改数据对象是
        数据对象是基本类型或者是结构的时候,可以使用指针或者是引用(基本类型建议指针)
        数据必须使用指针
        类的对象作为数据对象时,最好使用引用传递
五、 使用默认参数
    void sum(int num = 10);
    void sum(int sum)  此处不能再赋值 错误写法:void sum(int sum = 10); 
    {
        cout << sum <<endl;
    }
    注意: 1 使用默认函数时,声明和实现部分只能有一个赋值
          2 参数列表有多个参数时,在给默认参数进行赋值时,只能从右往左进行赋值
              正确的写法: void sum(int a, int b = 10, int c = 10);
              正确的调用: sum(1); sum(1, 2); sum(1, 2, 3);
              错误的写法: void sum(int a = 10, int b, int c = 10);
六 函数的重载  
    所谓函数的重载就是 多个函数,函数名相同,但是参数列表不同,比如:
    void num(int num1, int num2);   void num(double num1, double num2);
    voie num(int num1);             void num(double num1);
    
    注意: void sum(int&) 和 void sum(int) 是一样的,因为在调用的时候,都是一样的
        比如:  void sum(10); 这样的话就会报错,因为编译器不知道你调用的到底是哪个函数

    实际上,在函数内部进行调用的时候,是根据特征标来进行函数的调用
    比如 void sum(int); 和 void sum(float);是函数的重载
    但在执行的时候,编译器 重载决议 将 void sum(int); 编译为 void sum_int
    同理将 void sum(float); 编译为 void sum_float 
    所以实际上 void sum(int&) 和 void sum(int) 在编译时,都会编译为
    void sum_int
    
七 利用函数的重载进行对不同类型的数组排序
    
  main函数部分:
  
    #include <iostream>    
    #include "sort.hpp"

    using namespace std;

    int main()
    {
        int intArry[6] = {11, 66, 55, 44, 33, 22};
        double doubleArray[6] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};

        Show(intArry, 6);   显示排序前的数组
        Sort(intArry, 6);   对数组进行排序
        Show(intArry, 6);   再次显示

        Show(doubleArray, 6);  
        Sort(doubleArray, 6);
        Show(doubleArray, 6);

        return 0;
    }

排序的 sort.hpp 部分:

    #ifndef SORT_HPP_INCLUDED
    #define SORT_HPP_INCLUDED
    #include <iostream>
    using namespace std;

    void Sort(int [], int);   利用函数的重载进行排序
    void Sort(double [], int);

    void Show(int [], int);   利用函数的重载进行显示
    void Show(double [], int);


    #endif // SORT_HPP_INCLUDED

排序的 sort.cpp 部分:

    #include <iostream>
    #include "sort.hpp"

    using namespace std;

    void Sort(int Array[], int Length)   对int型的函数进行排序 
    {
        for(int i = 0; i < Length - 1; i++)
            {    
            for(int j = 0; j < Length - 1 - i; j++)
            {
                if(Array[j] > Array[j + 1])
                {
                    int temp;
                    temp = Array[j];
                    Array[j] = Array[j + 1];
                    Array[j + 1] = temp;
                }
            }
        }
        return;
    }

    void Sort(double Array[], int Length)   对double型的函数进行排序
    {
        for(int i = 0; i < Length - 1; i++)
        {
            for(int j = 0; j < Length - 1 - i; j++)
            {
                if(Array[j] > Array[j + 1])
                {
                    double temp;
                    temp = Array[j];
                    Array[j] = Array[j + 1];
                    Array[j + 1] = temp;
                }
            }
        }

        return;
    }

    void Show(int Array[], int Length)    对int型的函数进行排序
    {
        for(int i = 0; i < Length; i++)
        {
            cout << Array[i] << '\t';
        }
        cout << endl;
        return;
    }


    void Show(double Array[], int Length)   对double型的函数进行显示
    {
        for(int i = 0; i < Length; i++)
        {
            cout << Array[i] << '\t';
        }
        cout << endl;
        return;
    }    

  函数重载的意义:用同一个函数名,实现对不同数据类型的数组进行排序和显示
  缺点: 代码的重复率过高,不简洁

 

八  函数模板 
    一般函数模板的声明:template <typename T> void sum(T num1);
    其中T是一个虚拟的数据类型,会根据传入的实参而改变。
    
    所谓函数模板,实际上就是建立一个通用函数
    1. 函数定义时,不指定具体的数据类型(使用虚拟类型来代替)
    2. 函数在调用的时候,编译器会根据传入的实参来反推数据类型--类型的参数化
    
    注意:在声明模板函数的时候,模板函数的声明和实现必须都放在同一个文件夹中,不能分文件操作。
     
    模板函数的优点: 与函数的重载相比,减少了代码量,只需书写一个函数模板就可以实现
                    对不同数据类型的操作

    比如,用函数模板实现对不同数据类型的数组进行显示 :

        #include <iostream>
        #include "sort.hpp"
        using namespace std;
        
        template <typename T>
        void TShow(T TArray[], int Length)
        {
            for(int i = 0; i < Length; i++)
            {
                cout << TArray[i] << '\t';
            }
            cout << endl;
        }
        
        int main()
        {
            int intArray[] = {11, 66, 55, 44, 33, 22};
            double doubleArray[] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};
            
            TShow(intArray, sizeof(intArray) / sizeof(intArray[0]));
            TShow(doubleArray, sizeof(doubleArray) / sizeof(doubleArray[0]));
            return 0;
        }


    使用场合:

        在不同类型的数据有相同操作的时候,用函数模板,如果不同数据的操作不同,采用函数重载
        因为函数模板只有在业务逻辑一样,但是数据类型不一样的情况下才能使用。
    

未完待续~~~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章