4.C++中的函數重載,C++調用C代碼,new/delete關鍵字,namespace(命名空間)

来源:https://www.cnblogs.com/lifexy/archive/2018/02/15/8449703.html
-Advertisement-
Play Games

本章主要內容: 1)函數重載 2)C++調用C代碼 3)new/delete關鍵字實現動態記憶體分配 4)namespace命名空間 大家都知道,在生活中,動詞和不同的名詞搭配一起,意義都會大有不同,比如”玩”: 玩游戲 玩卡牌 玩足球 所以在C++中,便出現了函數重載(JAVA,c#等語言都有函數重 ...


本章主要內容:

  • 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\n",str);  
}

int func(int a)            //func2
{
   printf("a=%d\n",a);
}

int func(int a,int b)   //func3
{
   printf("a*b =%d\n",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 \n",add(1,3));
  return 0;
}

main.cpp里的__cplusplus巨集C++編譯器自帶的,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[],避免記憶體泄漏

 

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)使用整個命名空間:

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\n", i);     

    printf("Second::i = %d\n", Second::i);
    
    Position p = {2, 3};  
    printf("p.x = %d\n", p.x);
    printf("p.y = %d\n", p.y);

    return 0;
}

輸出結果:

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

 

未完待續,下章繼續學習C++中的強制轉換

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、前言 接著上一章的內容,繼續本章的學習。 二、內容 ...
  • 一、前言 接著前一章的內容,繼續本章的學習 二、內容 ...
  • 一、前言 接著上一章的內容,繼續本章的學習。 二、內容 ...
  • 我也在FreeCodeCamp上碰到這樣一道題: 刪除數組中的所有假值。 在JavaScript中,假值有false、null、0、”“、undefined 和 NaN。 對於NaN的判斷,JS提供了函數isNaN()。但是使用isNaN()函數只能判斷變數是否非數字,而無法判斷變數值是否為NaN。 ...
  • 一、前言 接著上一章的內容,繼續JQuery的學習 二、內容 ...
  • // A input { outline: none; } // B Input::-moz-focus-inner { border: none; } //加了ouline沒用,別死磕,重啟 ...
  • 使用分散式系統與在單機系統中處理問題有很大的區別,分散式系統帶來了更大的處理能力和存儲容量之後,也帶來了很多新的 "煩惱" 。在這一篇之中,我們將看看分散式系統帶給我們新的挑戰。 1.故障 當我們在使用單機系統時,它通常以一種相當可預測的方式工作:要麼它正常工作,要麼不工作。 而當我們在使用分散式系 ...
  • 源代碼是這樣:s=b'^SdVkT#S ]`Y\\!^)\x8f\x80ism'key=''for i in s: i=ord(i)-16 key+=chr(i^32)print (key)運行後出現了問題:ord() expected string of length 1, but int fou... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...