C++面試八股文:C++中,設計一個類要註意哪些東西?

来源:https://www.cnblogs.com/binarch/archive/2023/06/08/17467955.html
-Advertisement-
Play Games

某日二師兄參加XXX科技公司的C++工程師開發崗位第9面: > 面試官:C++中,設計一個類要註意哪些東西? > > 二師兄:設計一個類主要考慮以下幾個方面:1.面向對象的封裝、繼承及多態。2.`big three`或者`big five`。3.運算符和函數重載、靜態成員、友元、異常處理等相關問題。 ...


某日二師兄參加XXX科技公司的C++工程師開發崗位第9面:

面試官:C++中,設計一個類要註意哪些東西?

二師兄:設計一個類主要考慮以下幾個方面:1.面向對象的封裝、繼承及多態。2.big three或者big five。3.運算符和函數重載、靜態成員、友元、異常處理等相關問題。

面試官:請介紹一下麵向對象的三個特性。

二師兄:封裝是將類的函數和數據封裝起來,外部不能直接訪問類的數據,而是需要通過方法訪問數據。繼承是指一個類可以繼承另一個類的屬性和方法。多態是指一個對象可以表現出多種形態。

面試官:請問多態是如何實現的?

二師兄:多態的是通過父類的指針或引用指向子類的對象實現的。在對象中維護一個虛指針(vtptr),這個指針指向一個虛表(vtable),當用戶通過父類對象訪問子類的方法時,通過查詢虛表中對應的方法的地址,並跳轉到此地址執行間接訪問對象的方法。所以多態是有一點點運行時開銷的。

面試官:你剛纔所說的big threebig five是什麼?

二師兄:(嘿嘿,被裝到了)類的big three分別是拷貝構造函數(copy constructor)、拷貝賦值運算符(copy assignment)和析構函數。而類的big five則多了兩個,分別是移動構造函數(move constructor)和移動賦值運算符(move assignment)。後面兩個是C++11之後引入的。

面試官:好的。那你知道為什麼要引入移動構造和移動賦值嗎?

二師兄:主要是為了效率。移動構造和移動賦值不需要把所有的數據重新拷貝一遍,而是霸占了被移動對象的數據的所有權。代價是被移動對象在被移動後不能使用。

面試官:嗯。那你知道為什麼移動構造和移動賦值都要加上noexcept關鍵字嗎?

二師兄:額。。。好像不讓拋異常?

面試官:你知道類的靜態成員變數需要註意哪些問題嗎?

二師兄:要註意哪些問題?額。。。

面試官:在成員方法後加const是為什麼?

二師兄:主要是為了約束這個成員方法不更改對象的任何數據。

面試官:還有其他的原因嗎?

二師兄:好像沒有了吧。。。

面試官:類的成員方法可以通過const符號重載嗎?

二師兄:這個,,應該可以吧。。

面試官:你知道什麼是類的成員方法的引用限定符嗎?

二師兄:沒有聽說過耶。。。

面試官:好的,回去等通知吧。

讓我們來看一看今日二師兄的表現吧,

為什麼移動構造和移動賦值都要加上noexcept關鍵字?

因為在使用移動語義時,通常會將資源的所有權從一個對象轉移到另一個對象,而不是複製資源。如果拋出異常,那麼在轉移資源的過程中可能會出現問題,導致資源泄漏或其他不可預測的行為。

另外,加上 noexcept 關鍵字還可以提高代碼的性能,因為編譯器可以在不必要的情況下進行優化。

類的靜態成員變數需要註意哪些問題?

靜態成員變數的初始化順序是不確定的。如果一個靜態成員變數依賴於另一個靜態成員變數的值,要確保第二個靜態化成員先被初始化,否則程式可能會出現未定義的行為。

靜態成員變數的值可以被多個實例同時修改,因此在多線程訪問靜態成員時要註意數據競爭問題。靜態變數的生命周期與程式的生命周期相同,因此它們可能會占用大量的記憶體。

在成員方法後加const是為什麼?

一是可以約束此方法不會更改對象的任何數據。二是cosnt對象也可以訪問此成員方法。

#include <iostream>
struct Foo
{
    void f1(){std::cout <<"f1" << std::endl;}
    void f2() const{std::cout <<"f2" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Foo foo;
    foo.f1();
    foo.f2();
    const Foo& foo2 = foo;
    foo2.f1();  //這裡無法通過編譯,因為const對象無法訪問非const 方法
    foo2.f2();  //這裡可以通過編譯
}

類的成員方法可以通過const符號重載嗎?

這是一個很好的問題,估計很多人沒有思考過。先說答案,底層const可以,而頂層const不可以。

#include <iostream>
struct Foo{};
struct Goo
{
    void f1(Foo& f){std::cout <<"non const function" << std::endl;}
    void f1(const Foo& f){std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Foo foo;
    Goo goo;
    goo.f1(foo);    //無法通過編譯,error: ‘void Goo::f1(Foo)’ cannot be overloaded with ‘void Goo::f1(Foo)’
    return 0;
}

當我們把頂層const改為底層const

#include <iostream>
struct Foo{};
struct Goo
{
    void f1(Foo& f){std::cout <<"non const function" << std::endl;}
    void f1(const Foo& f){std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Foo non_const_foo;
    const Foo const_foo;
    Goo goo;
    goo.f1(non_const_foo);    //可以通過編譯	non const function
    goo.f1(const_foo);    //可以通過編譯 const function
    return 0;
}

那麼我們能否通過在函數括弧後加上const來重載函數呢?

#include <iostream>
struct Goo
{
    void f1() {std::cout <<"non const function" << std::endl;}
    void f1() const{std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Goo non_const_goo;
    const Goo const_goo;
    non_const_goo.f1();   
    const_goo.f1();   
    return 0;
}

答案是肯定的,因為const_goo.f1() 可以等同於f1(const Goo* goo),也是底層const

最後一個問題雖然簡單,但我相信至少有80%的C++程式員不知道是什麼,

什麼是類的成員方法的引用限定符嗎?

類的成員方法的引用限定符是 C++11 中引入的一種新特性,用於指定成員方法的參數是左值引用還是右值引用。

#include <iostream>
struct Foo
{
    void f1() & {std::cout << "only left reference can call this function" << std::endl;}
    void f1() && {std::cout << "only right reference can call this function" << std::endl;}
};
int main(int argc, char const *argv[])
{
    Foo foo;
    foo.f1();       //left reference
    Foo().f1();     //right reference
    return 0;
}

好了,今日份面試到這裡就結束了,小伙伴們,對於今天二師兄的面試,能打幾分呢?如果是你,以上的問題都能回答的上來嗎?

關註我,帶你21天“精通”C++!(狗頭)


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

-Advertisement-
Play Games
更多相關文章
  • vue3 偵聽器 在Vue3中,偵聽器的使用方式與Vue2相同,可以使用watch選項或$watch方法來創建偵聽器。不同之處在於,Vue3中取消了immediate選項,同時提供了新的選項和API。 創建偵聽器 可以使用watch選項或$watch方法來創建偵聽器,語法與Vue2相同。示例如下: ...
  • 報錯信息如下: 代碼如下: <!DOCTYPE html> <html> <body> <div id="demo"> <h1>XMLHttpRequest 對象</h1> <button type="button" onclick="loadDoc()">更改內容</button> </div> ...
  • 一. 目標 個人賬號的設置記憶功能-避免用戶每次登錄之後重新對錶單欄位做展示設置 二、存儲方案 輕量方案 結合localstorage低容量存儲(5M),根據LRU只存最近訪問的20至30張表格列配置數據 全量方案 大記憶體G級別,使用indexedDb進行存儲,有多少表格操作列數據就存多少, 結合第 ...
  • ###為什麼建議使用對象來替換枚舉? ### 在設計模型時,我們經常會使用枚舉來定義類型,比如說,一個員工類 Employee,他有職級,比如P6/P7。順著這個思路,設計一個 Level 類型的枚舉: ``` class Employee { private String name; /** * ...
  • 摘要:本文將探索內核中解析PE文件的相關內容。 本文分享自華為雲社區《驅動開發:內核PE結構VA與FOA轉換》,作者: LyShark 。 本章將探索內核中解析PE文件的相關內容,PE文件中FOA與VA、RVA之間的轉換也是很重要的,所謂的FOA是文件中的地址,VA則是記憶體裝入後的虛擬地址,RVA是 ...
  • WFP框架是微軟推出來替代TDIHOOK傳輸層驅動介面網路通信的方案,其預設被設計為分層結構,該框架分別提供了用戶態與內核態相同的AIP函數,在兩種模式下均可以開發防火牆產品,以下代碼我實現了一個簡單的驅動過濾防火牆。WFP 框架分為兩大層次模塊,用戶態基礎過濾引擎`BFE (BaseFilteri... ...
  • *以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接[ 微信公眾號「ENG八戒」](https://mp.weixin.qq.com/s/Xd_FwT8E8Yx9Vnb64h6C8w) > 帶給現代 C++ 性能飛躍的特性很多,今天一邊聊技術,一邊送福利! ![](https://img2023. ...
  • 環境:CentOS 7.6_x64 Python版本 :3.9.12 pjsip版本:2.13 一、背景描述 pjsip地址:https://www.pjsip.org/ GitHub地址:https://github.com/pjsip/pjproject pjsip文檔地址:https://do ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...