【面試題】C++系列(一)

本專欄文章持續更新,新增內容使用藍色表示。

C++面向對象的三大特性:封裝,繼承,多態

(1)封裝是將數據和函數組合到一個類里。主要目的是隱藏內部的實現細節,僅暴露必要的接口給外部。通過封裝,可以控制類成員的訪問級別(例如:public、protected 和 private)。

(2)繼承是派生類獲得基類的屬性和方法。提高代碼復用性。public、protected、private。

(3)多態是同一個函數在不同的對象上表現形式不同。主要通過重載和重寫實現的,重載在編譯階段完成,屬于靜態的多態,重寫是利用虛函數和動態綁定實現,屬于動態多態。

【補充】重載是利用名稱修飾技術來改函數名,區分參數列表不同的參數。

解釋虛函數與虛函數表

(1)虛函數是C++中實現運行時多態的機制。重寫是利用虛函數和動態綁定實現的,在基類函數前加上virtual,派生類中重寫,運行時就會根據對象的實際類型去調用。

(2)虛函數表:每個有虛函數的類都會維護一個虛函數表(vtable),存儲了該類所有虛函數的指針。調用虛函數時,程序通過vptr找到虛函數表,再通過表中的函數指針調用正確的函數實現。

【補充】對象創建時,編譯器會在對象內存布局的最前面加一個vptr指針,指向該類的虛函數表。調用虛函數時,程序通過vptr找到虛函數表,再通過表中的函數指針調用正確的函數實現。

【補充】虛函數表在內存中包含:

指向類型信息的指針(RTTI),該類所有虛函數的實際地址,可能包含繼承鏈中父類的虛函數地址,派生類的虛函數表會繼承基類的虛函數表內容,并用派生類重寫的函數地址覆蓋對應的表項。純虛函數在虛函數表中的位置會被保留,但指向一個特殊的"未實現"處理函數。

你對重載運算符了解多少?

首先只能重載已有的運算符,并且運算符的優先級、操作數個數、結合律和原來的一致。

其次是重載方式分為成員運算符和非成員運算符,區別是成員運算符少一個參數。

【補充】下標運算符、箭頭運算符必須是成員運算符

重載、重寫與隱藏

(1)重載是指相同作用域(命名空間、類)內有相同的函數名,但是參數列表不同。它根據參數不同來調用不同的函數。

【補充】返回值不能作為重載的區分條件

(2)重寫是指在派生類中重新定義基類中的方法。在需要改變或擴展基類方法時使用。

【補充】基類中被重寫的函數有virtual修飾,派生類在重寫時要有相同的名稱、參數列表、返回類型,只有函數體內不同。

(3)隱藏是指派生類的函數屏蔽了與其同名的基類函數。注意只要同名函數,不管參數列表是否相同,基類函數都會被隱藏。

【面試】在隱藏或者重寫的情況下,如何調用基類的函數?

答:使用作用域解析符::,類名::函數名(),或者通過基類指針或引用調用。

malloc、new,free、delete的異同

malloc和free是C語言中的庫函數,而new和delete是C++ 運算符,會調用它的構造和析構函數,而且運算符可以被重載。不過new和delete的底層會調用malloc和free。

【補充】malloc和free需要指定大小,返回的是void*類型,需要進行強制類型轉換。

【補充】new的底層會調用operator new,而它又會使用malloc分配內存,而malloc的底層是系統調用。delete 先調用析構函數釋放對象資源,再通過 operator delete釋放內存,調用free 直接歸還內存給系統。

malloc 1KB和1MB 有什么區別?

malloc() 并不是系統調用,而是 C 庫里的函數,用于動態分配內存。它的源碼里默認定義了一個閾值:

如果用戶分配的內存小于閾值,則通過 brk() 系統調用從堆分配內存。

如果用戶分配的內存大于閾值,則通過 mmap() 系統調用在文件映射區域分配內存;

字節序問題

大端字節序:高位字節存儲在低地址處,低位字節存儲在高地址處

低位字節序:低位字節存儲在低地址處,高位字節存儲在高地址處

【補充】網絡字節序使用的是大端字節序

Explicit關鍵字

用于防止隱式轉換。防止編譯器自動執行預期外的類型轉換,提高代碼的安全性。

defineconstinlinetypedef的區別

define,發生在預處理階段,用于定義宏、常量,但是定義的常量沒有類型檢查,作用域是全局作用域,不受命名空間限制。

Const發生在編譯階段,定義的常量是帶類型的,會存儲在內存中,有利于類型轉換。

Inline內聯函數,在函數聲明前加上 inline 關鍵字。

typedef 發生在編譯階段處理的,有更嚴格的類型檢查,用于為現有類型創建別名。

【補充】定義為內聯函數不一定會進行內聯,就像mysql的索引優化一樣,編譯器內部會進行判斷,選擇最優的結果。優點是類型安全、可調試、可優化,缺點是函數體被復制多次,占用更多的代碼段空間,某些情況下會導致代碼膨脹,所以只適用于簡單代碼。

C++類對象的初始化

(1)基類初始化

如果當前類繼承自一個或多個基類,它們將按照聲明順序進行初始化,有虛繼承和一般繼承的情況下,優先虛繼承。

(2)成員變量初始化

按照在類定義中的聲明順序進行初始化(只與聲明順序有關)。

(3)執行構造函數

深copy與淺copy

淺拷貝是復制指針值,也就是地址,這會導致新舊對象共享同一塊內存。而深拷貝不僅復制指針,還會創建新的內存空間去拷貝數據,每個對象都有自己獨立的副本。

【補充】默認情況下,C++使用淺拷貝,效率高,但是有安全隱患:比如一個對象釋放了內存,另一個對象的指針就會變成懸空的,訪問會導致未定義行為;其次,當多個對象析構時,會多次釋放同一塊內存,造成程序崩潰。

【補充】深拷貝,需要自定義拷貝構造函數和賦值運算符重載。拷貝構造函數中,要為指針成員分配新的內存,并拷貝原始對象的數據;賦值運算符重載中,除了拷貝數據外,還需要先釋放對象原有的內存,處理自賦值的情況。

使用智能指針,shared_ptr共享所有權,unique_ptr獨占所有權。

Static類成員函數和類靜態變量

static 函數是靜態成員函數,它與類本身相關,而不是與類的對象。可以將其視為在類作用域下的全局函數。

【補充】靜態函數沒有 this 指針,不能訪問任何非靜態成員變量。

C++11新特性

(1)auto關鍵字編譯器自動推斷變量類型。

(2)基于范圍的for循環,簡化容器遍歷語法

(3)智能指針:引入內存管理類,減少內存泄漏:

std::unique_ptr:獨占所有權的智能指針,

std::shared_ptr:共享所有權的智能指針,

std::weak_ptr:不增加引用計數的智能指針。

(4)移動語義和右值引用,提高資源利用效率。

(5)Lambda表達式,支持匿名函數。

(6)nullptr更安全的空指針常量。

(7)委托構造函數,構造函數可以調用同類其他構造函數。

右值引用

右值引用簡單來說,就是可以延長某塊內存的存活時間。一般情況下,變量生命周期結束,它就被銷毀了,比如,函數中的臨時變量,在函數退出之后銷毀。如果想要延長使用時間,就可以使用右值引用,此時生命周期變為右值引用的生命周期。

【補充】右值引用構造函數(移動構造函數),復用另外一個對象中的資源(堆內存)。移動構造對資源進行了轉移,而普通的拷貝構造函數會使得多個對象的指針指向同一塊內存。

【補充】左右值不是等號的左右,關于左值有個關鍵字是lvalue(locator value),字面意思是可通過地址定位到這個數據,所以左值是可以進行取地址操作。右值是rvalue(read value),只讀的數據。所以一般能進行取地址操作的是左值,不能的是右值。

【補充】不管是左值引用還是右值引用都是別名,不占用內存空間。實現方面右值引用比左值引用多寫一個取地址符。語法上我們只能通過右值去初始化右值引用。同類型的左值、右值引用,右值常量引用等都可以用來初始化常量左值引用(const T&)。

智能指針

(1)std::unique_ptr (獨占指針)

特點:獨占所有權,同一時間只能有一個unique_ptr指向特定對象

不能復制,但可以通過std::move轉移所有權,離開作用域時自動釋放所管理的內存,零開銷(與原始指針相比幾乎沒有額外成本)

std::unique_ptr<MyClass> ptr(new MyClass());// 或者更好的方式(C++14起):auto ptr = std::make_unique<MyClass>();

(2)std::shared_ptr (共享指針)???????? 可以使用std::make_shared

特點:共享所有權,多個shared_ptr可以指向同一個對象

使用引用計數機制跟蹤資源,當最后一個shared_ptr被銷毀時釋放資源,需要額外內存,有少量額外開銷

(3)std::weak_ptr (弱指針)

特點:不增加引用計數,不會阻止對象被銷毀

用于解決shared_ptr的循環引用問題,必須轉換為shared_ptr才能訪問對象

static_cast、dynamic_cast、?const_cast、?reinterpret_cast類型轉換

(1)static_cast在編譯時執行類型轉換,在進行指針或引用類型轉換時,需要自己保證合法性。如果想要運行時類型檢查,可以使用dynamic_cast進行安全的向下類型轉換

(2)dynamic_cast在C++中主要應用于父子類層次結構中的安全類型轉換。

它在運行時執行類型檢查,因此相比于static_cast,它更加安全

dynamic_cast <new_type> (expression)

(3)const_cast
new_type 必須是一個指針、引用或者指向對象類型成員的指針。當需要使用const對象調用非const成員函數時,可以使用const_cast刪除對象的const屬性

const_cast <new_type> (expression)

(4)?reinterpret_cast

reinterpret_cast用于在不同類型之間進行低級別的轉換。

reinterpret_cast <new_type> (expression)

Lamada表達式

Lambda 表達式是一種匿名函數,可以在需要的地方內聯定義函數,不用單獨聲明命名函數。作為回調函數時,常用。

[capture](parameters) -> return_type {// 函數體}

捕獲列表 (capture):定義哪些外部變量可以在 lambda 體內使用

參數列表 (parameters):與普通函數參數類似

返回類型 (return_type):可選的,編譯器通常可以自動推導

函數體:包含 lambda 要執行的代碼

map、set是怎么樣實現的,紅黑樹是怎么樣能夠同時實現這兩種容器?為什么使用紅黑樹?

(1)底層都是以紅黑樹的結構實現,插入刪除等操作都在對數級別O(log n)完成的,比較高效;

(2)通過定義了模版特化和仿函數,使用同一棵紅黑樹:基于模板的RBTree<Key, Value, KeyOfValue, Compare>。但是不同節點數據:set:Value = Key,直接存值,map:Value = pair<const Key, T>,存鍵值對。通過仿函數KeyOfValue從Value中提取比較鍵,set用Identity:直接返回值,map用SelectFirst。

(3)因為map和set要求是自動排序的,紅黑樹能夠實現這一功能,而且時間復雜度比較低。

了解RAII嗎?

RAII全稱是“Resource Acquisition is Initialization”,“資源獲取即初始化”, 資源生命周期與對象生命周期綁定,簡單來說就是對象構造時獲取資源,析構時自動釋放資源。智能指針(unique_ptr、shared_ptr、weak_ptr)是RAII的典型實現。


如有問題或建議,歡迎在評論區中留言~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95798.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95798.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95798.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

當沒辦法實現從win復制東西到Linux虛擬機時的解決辦法

① 先確認是否已安裝bash復制sudo apt list --installed | grep open-vm-tools如果 沒有任何回顯 → 沒裝&#xff0c;跳到 ③如果看到 open-vm-tools 已安裝 → 繼續 ②② 啟動正確的服務&#xff08;單詞別打錯&#xff09;bash復制systemctl status vmtoolsd # 查看…

用Markdown寫自動化用例:Gauge實戰全攻略!

你作為一名自動化測試工程師&#xff0c;正在為一個復雜的Web應用編寫測試腳本&#xff1a;傳統工具要求寫大量代碼&#xff0c;維護起來像解謎游戲&#xff0c;團隊非技術成員完全插不上手。這時&#xff0c;Gauge這個“自動化神器”如魔法般出現——它允許用Markdown寫可讀的…

Unity開發保姆級教程:C#腳本+物理系統+UI交互,3大模塊帶你通關游戲開發

文章目錄基礎概念Unity開發環境搭建版本選擇&#xff1a;為什么2021 LTS是最佳起點&#xff1f;三步安裝&#xff1a;從下載到項目創建界面認知&#xff1a;5分鐘掌握核心操作區配置優化&#xff1a;讓開發更順暢驗證環境&#xff1a;創建你的第一個CubeC#基礎語法與Unity腳本結…

Depth Anything V2論文速讀

這篇論文主要講了兩方面1.為了解決模型在正常標注的現實圖像上訓練的缺陷問題、提出了新的模型訓練數據和訓練方法真實標記圖像存在缺點&#xff1a;標簽噪聲&#xff08;深度傳感器可能存在空洞、玻璃等物體反射導致精度不準確&#xff09;、標簽細節粗糙&#xff08;深度圖邊…

數據庫原理及應用_數據庫管理和保護_第5章數據庫的安全性_理論部分

前言 "<數據庫原理及應用>(MySQL版)".以下稱為"本書"中第5章前6節內容 引入 數據庫的安全性是非常重要的,表現在兩個方面:一數據的訪問權限,二數據的物理安全.本書在這一章前6節基本上都是理論性的內容,選擇其中重要部分進行解讀. 5.1數據庫安全性…

QT6 配置 Copilot插件

下載項目&#xff1a;解壓 GitHub - github/copilot.vim: Neovim plugin for GitHub Copilot Node.js必須安裝 Node.js — Download Node.js 例如先安裝一個qt6 ,qt Cteatror選擇新版本的 設置 效果&#xff0c;注釋里面寫要求&#xff0c;tab同意 #include "mainwindow…

ArcGIS學習-15 實戰-建設用地適宜性評價

選定參評因子 高程坡度河流道路土地利用 確定因子分析標準 以下僅參數僅做展示&#xff0c;并非合理的數值 高程 0-100m&#xff1a;100 分&#xff0c;此高程范圍通常地勢較為平坦&#xff0c;建設成本相對較低&#xff0c;適宜建設。100-200m&#xff1a;70 分&#xff…

[C/C++學習] 7.“旋轉蛇“視覺圖形生成

參考文獻: 童晶. C和C游戲趣味編程[M].人民郵電出版社.2021. 一.弧度制和角度制的轉換 弧度制數值和角度對應表: (PI為圓周率&#xff0c;值為3.1415926)弧度制角度制00PI/630PI/360PI/2902*PI/3120PI1802*PI360二.扇形的繪制 easyx的solidpie( )函數用于在一個矩形區域內繪制…

自然語言處理之PyTorch實現詞袋CBOW模型

在自然語言處理&#xff08;NLP&#xff09;領域&#xff0c;詞向量&#xff08;Word Embedding&#xff09;是將文本轉換為數值向量的核心技術。它能讓計算機“理解”詞語的語義關聯&#xff0c;例如“國王”和“女王”的向量差可能與“男人”和“女人”的向量差相似。而Word2…

TCP, 三次握手, 四次揮手, 滑動窗口, 快速重傳, 擁塞控制, 半連接隊列, RST, SYN, ACK

目錄 TCP 是什么&#xff1a;面向連接 可靠 字節流三次握手&#xff1a;為什么不是兩次四次揮手與 TIME_WAIT&#xff1a;誰等誰序列號/確認號與去重、排序、確認重傳機制&#xff1a;超時重傳與快速重傳滑動窗口與流量控制擁塞控制&#xff1a;慢啟動/擁塞避免/快重傳/快恢…

CentOS 7.2 虛機 ssh 登錄報錯在重啟后無法進入系統

文章目錄前言1. 故障描述2. 故障診斷3. 故障原因4. 解決方案總結前言 上周幫用戶處理了一個 linux 虛擬機在重啟后無法正常進入操作系統的故障&#xff0c;覺得比較有意思&#xff0c;在這里分享給大家。 1. 故障描述 事情的起因是一臺系統版本為 CentOS 7.2 的 VMware 虛擬機…

《從使用到源碼:OkHttp3責任鏈模式剖析》

一 從使用開始0.依賴引入implementation ("com.squareup.okhttp3:okhttp:3.14.7")1.創建OkHttpClient實例方式一&#xff1a;直接使用默認配置的Builder//從源碼可以看出&#xff0c;當我們直接new創建OkHttpClient實例時&#xff0c;會默認給我們配置好一個Builder …

安裝3DS MAX 2026后,無法運行,提示缺少.net core的解決方案

今天安裝了3DS MAX 2026&#xff08;俗稱3DMAX&#xff09;&#xff0c;安裝完畢后死活運行不了。提示如下&#xff1a; 大意是找不到所需的.NET Core 8庫文件。后來搜索了下&#xff0c;各種文章說.NET CORE和.NET FRAMEWORK不是一個東西。需要單獨下載安裝。然后根據提示&…

FastAPI + LangChain 和 Spring AI + LangChain4j

FastAPI+LangChain和Spring AI+LangChain4j這兩個技術組合進行詳細對比。 核心區別: 特性維度 FastAPI + LangChain (Python棧) Spring AI + LangChain4j (Java棧) 技術棧 Python生態 (FastAPI, LangChain) Java生態 (Spring Boot, Spring AI, LangChain4j) 核心設計哲學 靈活…

Apache 2.0 開源協議詳解:自由、責任與商業化的完美平衡-優雅草卓伊凡

Apache 2.0 開源協議詳解&#xff1a;自由、責任與商業化的完美平衡-優雅草卓伊凡引言由于我們優雅草要推出收銀系統&#xff0c;因此要采用開源代碼&#xff0c;卓伊凡目前看好了一個產品是apache 2.0協議&#xff0c;因此我們有必要深刻理解apache 2.0協議避免觸犯版權問題。…

自學嵌入式第37天:MQTT協議

一、MQTT&#xff08;消息隊列遙測傳輸協議Message Queuing Telemetry Transport&#xff09;1.MQTT是應用層的協議&#xff0c;是一種基于發布/訂閱模式的“輕量級”通訊協議&#xff0c;建構于TCP/IP協議上&#xff0c;可以以極少的代碼和有限的帶寬為連接遠程設備提供實時可…

RabbitMQ--延時隊列總結

一、延遲隊列概念 延遲隊列&#xff08;Delay Queue&#xff09;是一種特殊類型的隊列&#xff0c;隊列中的元素需要在指定的時間點被取出和處理。簡單來說&#xff0c;延時隊列就是存放需要在某個特定時間被處理的消息。它的核心特性在于“延遲”——消息在隊列中停留一段時間…

Java 提取 PDF 文件內容:告別手動復制粘貼,擁抱自動化解析!

在日常工作中&#xff0c;我們經常需要處理大量的 PDF 文檔&#xff0c;無論是提取報告中的關鍵數據&#xff0c;還是解析合同中的重要條款&#xff0c;手動復制粘貼不僅效率低下&#xff0c;還極易出錯。當面對海量的 PDF 文件時&#xff0c;這種傳統方式更是讓人望而卻步。那…

關鍵字 const

Flutter 是一個使用 Dart 語言構建的 UI 工具包&#xff0c;因此它完全遵循 Dart 的語法和規則。Dart 中的 const 是語言層面的特性&#xff0c;而 Flutter 因其聲明式 UI 和頻繁重建的特性&#xff0c;將 const 的效能發揮到了極致。Dart 中的 const&#xff08;語言層面&…

Ubuntu22.04中使用cmake安裝abseil-cpp庫

Ubuntu22.04中使用cmake安裝abseil-cpp庫 關于Abseil庫 Abseil 由 Google 的基礎 C 和 Python 代碼庫組成&#xff0c;包括一些正支撐著如 gRPC、Protobuf 和 TensorFlow 等開源項目并一起 “成長” 的庫。目前已開源 C 部分&#xff0c;Python 部分將在后續開放。 Abseil …