zoukankan      html  css  js  c++  java
  • 4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)

    本章主要内容:

    • 1)函数重载 
    • 2)C++调用C代码 
    • 3)new/delete关键字实现动态内存分配
    • 4)namespace命名空间

    大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比如”玩”:

    • 游戏
    • 卡牌
    • 足球

    所以在C++,便出现了函数重载(JAVA,c#等语言都有函数重载)

    1.函数重载(overload)

    表示有多个相同的函数名(类似上面的”玩”),但是参数表不同(类似上面的名词)

    参数表不同主要有以下几种

    • 1) 参数个数不同
    • 2) 参数类型不同
    • 3) 参数顺序不同

    1.1举个栗子

    #include <stdio.h>
    
    int func(char *str)      //func1
    {
       printf("str=%s
    ",str);  
    }
    
    int func(int a)            //func2
    {
       printf("a=%d
    ",a);
    }
    
    int func(int a,int b)   //func3
    {
       printf("a*b =%d
    ",a*b);
    }
    
    
    int main()
    {
     char s[10]="hello";
    
     func(s);
     func(10);
     func(5,5);           
    }        

    输出结果:

    str=hello
    a=10
    a*b =25

    通过上个栗子可以看到,函数名相同,参数不同,而意义却大有不同.

    1.2那这些重载函数的入口地址是否相同

    修改上面栗子的main()函数,如下图所示:

    可以看到输出结果,每个函数的入口地址都不一样(重载函数的入口地址,必须使用强制转换来获取)

    也可以通过nm命令来查看符号表,如下图所示:

     

    注意:

    • 重载函数需要避免使用参数默认值
    • 调用重载函数时,只会匹配函数参数表,与函数返回值无关
    • 函数重载必须发生在同一个作用域
    • 重载函数的入口地址,不能直接通过函数名来获取

    2.C++C代码相互调用

    C++想调用C里的某个函数时,则使用extern “C”

    还是举个栗子,通过C++调用C里面的add()函数

    1) 首先创建3个文件

     

    add.c代码如下:

    #include "add.h"
    
    int add(int a,int b)
    {
      return a+b;
    }

    add.h代码如下:

    int add(int a,int b);

    main.cpp代码如下:

    #include <stdio.h>
    
    #ifdef __cplusplus
    extern "C"     //通过C方式来编译add.h,也就是add()函数
    {
      #include "add.h"
    }
    #endif
    
    int main()
    {
      printf("%d 
    ",add(1,3));
      return 0;
    }

    main.cpp里的__cplusplusC++编译器自带的,extern "C"只有C++里才有定义.

    所以通过__cplusplus宏判断,可以使main.cppCC++编译器下都能编译运行.

    2)编译运行:

    gcc  -c  add.c                    //生成add.o文件
    g++  -o  main   main.cpp  add.o   //生成main可执行文件
    ./main

    3)输出结果:

     

    3. C++中的动态内存分配

    3.1 回顾C:

    C语言中,大家都知道使用malloc()free(),比如:

    int *p = malloc(10*sizeof(int));  //申请10个int型空间 
    if(p)
    {
      ... ...
      free(p);
    }

    从上面栗子,可以看到C是通过库函数完成内存分配的

    3.2而在C++,则通过new关键字进行内存申请,delete关键字进行内存释放,比如:

    • Type: 指数据类型,比如int,char,float
    • N:  指申请的数组个数大小

    除了上图例子外,new关键字还可以通过分配并初始化(类似calloc()函数)

    例如:

    int *p1= new int(1);       //动态分配一个int空间给p1,并赋值为1
    
    float *p2=new float(2.0f);  //2.0后面加f,表示2.0是个float类型
    
    char *p3=new char('c');

    注意:

    • 释放数组的空间时,必须使用delete[],而不是delete,避免内存泄漏
    • 使用new时,默认值为随机值,而对于new()时,则为0,比如: int *p = new int();  //默认值为0

    3.3 以string为例,创建string数组

    #include <iostream> 
    #include <string>
    using namespace std; 
     
    int main()
    { 
         string *p = new string[10];
         
         for(int i=0;i<10;i++)
         p[i] = "123";
         
        for(int i=0;i<10;i++)
        cout<<p[i]<<endl;
     
        delete[] p;
    }

    3.3 二维指针示例

     以string二维指针为例:

    #include <iostream> 
    #include <string>
    using namespace std; 
    
     
    int main()
    { 
        string **p  = new string*[4];        //创建行数 
        
        for(int i=0;i<4;i++)
           p[i] = new string[3];                //创建列数 
        
        
          for(int i=0;i<4;i++)
          for(int j=0;j<3;j++)
           {
                   p[i][j]="123";
                   
                cout<<p[i][j] <<endl; 
           } 
        
        
        for(int i=0;i<4;i++)
            delete[]  p[i] ;                
             
         delete[]  p;  
    }

    4.C++中的命名空间(namespace)

    4.1回顾C:

    大家都知道,C语言中,当编译多个C文件时,可能会遇到同名全局标识符的错误,这是因为C语言中的所有全局标识符都是共享同一个作用域

     

    4.2所以C++中便提出命名空间(namespace)的概念

    • 命名空间会将全局作用域分成不同部分的命令空间,可以将类,对象,函数等聚集在一个namespace
    • 不同命名空间中的标识符可以同名
    • 命名空间可以相互嵌套,也就是说A命令空间里可以再次定义B命令空间
    • C++,全局作用域也叫默认命名空间

    4.3命名空间(namespace)的使用

    1)定义一个命名空间

    namespace name   //定义一个命名空间,名为name
    {
         int varialbe;
         //... ...
    }

    2)使用整个命名空间name,并将该空间设为当前默认命名空间:

    using namespace name;   

    3)使用全局命名空间中的变量

    ::varialbe;      //由于::前面没有命名空间名字,所以使用全局变量

    4)使用某个命名空间中的变量:

    using name::variable      //使用name空间里的variable变量

    4.4 举个栗子

    #include <stdio.h>
    
    namespace First //定义First命名空间
    {
        int i = 0;
    }
    
    namespace Second //定义Second命名空间
    {
        int i = 1;namespace Internal //在Second里,再次定义一个Internal空间(实现嵌套)
        {
            struct Position
            {
                int x;
                int y;
            };
        }
    }
    
    int main()
    {
        using namespace First;             //使用First整个命名空间,成为该main()的默认空间
        using Second::Internal::Position; //使用Second->Internal空间里的Position结构体
    
        printf("First::i = %d
    ", i);    
    
        printf("Second::i = %d
    ", Second::i);
        
        Position p = {2, 3};  
        printf("p.x = %d
    ", p.x);
        printf("p.y = %d
    ", p.y);
    
        return 0;
    }

    输出结果:

    First::i = 0
    Second::i = 1
    p.x = 2
    p.y = 3

     

    下章接着来学习: 5.C++里的4种新型类型转换

     

     

  • 相关阅读:
    MySQL Generic Binaries包和RPM包的区别?
    实体零售如何构建数据管理体系及未来方向
    python3 数据分析
    power designer 资料库表查询
    PowerDesigner 连接资料库
    电商数据分析的基本指标体系
    初中数学动点最值问题19大模型+例题详解
    初中数学全年级26个专题知识点精编汇总
    Python数据分析学习路径拆解及资源推荐
    十种常用的数据分析方法
  • 原文地址:https://www.cnblogs.com/lifexy/p/8449703.html
Copyright © 2011-2022 走看看