記錄一些面試遇到的問題

重載和重寫的區別

重載是overload,覆蓋是override
在這里插入圖片描述
重載屬于編譯時多態,覆蓋屬于運行時多態

運行時多態和編譯時多態

運行時多態指的是在運行的時候才知道要調用哪一個函數,編譯時多態是指在編譯的時候就知道調用哪一個函數。

運行時多態

可以使得父類指針調用子類函數,當然子類指針也可以調用父類函數

#include <iostream>class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived class" << std::endl; }
};int main() {Base* ptr;Derived obj;ptr = &obj;ptr->show();  // 調用 Derived::show(),發生運行時多態
}

by the way,如果代碼不慎寫為了這樣,編譯器也不會報錯,而是友善提示:
函數 ‘show’ 從類 ‘Base’ 中隱藏了一個非虛擬函數

#include <iostream>class Base {
public:void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() { std::cout << "Derived class" << std::endl; }
};int main() {Base* ptr;Derived obj;ptr = &obj;ptr->show();  // 調用 Derived::show(),發生運行時多態
}

因為在C++ 規定,如果子類定義了與基類同名的函數,則基類中的所有同名函數都會被隱藏(即使參數列表不同)。
那如果有一個需求,首先滿足Derived類繼承了Base,同時有自己的show函數(參數列表和Base不一樣,因此單純的override是不行的),可以在Derived類里添加一句using Base::show;即可。

class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:using Base::show;void show(int a)  { std::cout << "Derived class" <<a<< std::endl; }
};int main() {Derived* ptr; //注意這里變為了Derived*Derived obj;ptr = &obj;ptr->show();ptr->show(1);
}

如果有對多態學術不精,只記得在虛函數的加持下可以使得父類指針訪問子類函數,而將上述代碼寫為了

    Base* ptr; Derived obj;ptr = &obj;ptr->show();ptr->show(1);

代碼是不會通過檢查的,因為父類指針可以調用子類的函數,但前提是 這個函數必須在父類中聲明為 virtual,這樣才能實現運行時多態(動態綁定)。
雖然我們在父類里有show()這個函數,但show(int) 不是 Base 類的虛函數,所以 Base* 看不到 Derived 里的 show(int),導致編譯錯誤。

編譯時多態

特點:

  1. 同一作用域內,多個函數同名但參數列表不同(參數個數或類型不同)。
  2. 編譯時根據函數調用的參數選擇具體的函數(編譯器做“名字修飾(Name Mangling)”處理)。
  3. 不會引發運行時開銷,函數的匹配完全在編譯階段完成。

繼承

公有繼承
class Base {
public:int a;
protected:int b;private:int c;
};class Derived : public Base {void print(){cout<<b;}
};int main() {Derived* ptr;Derived obj;ptr = &obj;cout << ptr->a;
}

基類的 public 變成 public,protected 變成 protected,private 仍然是 private。

保護繼承

在這里插入圖片描述基類的 public 和 protected 變成 protected,private 不可訪問。

私有繼承

private(私有繼承):基類的 public 和 protected 變成 private,private 不可訪問。

多繼承下的菱形繼承

sizeof

虛函數的size

在這里插入圖片描述
輸出的結果為:
在這里插入圖片描述
這是因為虛函數引入了虛表,因此需要額外存儲一個虛表指針,64位系統下size = 8B。
如果再加上一個int,則為16(需要做到對齊,因此還補了4B)
在這里插入圖片描述
多繼承的情況下:
輸出結果為16,因為繼承了A和B,因為有兩個虛指針
在這里插入圖片描述

普通函數的size

普通函數size = 1

struct的size

struct也要遵循內存對齊,對齊原則是結構體或類的整體大小必須是其最大對齊數的整數倍(最大成員的對齊值
因此比如

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
因為char[]里有一個’\0’,因此size是6

指針與引用

先來個很經典的題

void GetMemory1(char* p){p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(str);strcpy(str,"hello");printf(str);
}int main() {Test1();
}

這樣會導致程序直接崩潰,原因是GetMemory1傳入的函數是指針。注意,這里進行的是值傳遞,也就是說,我們傳入的是str的復制值,因此在GetMemory1里修改p對外面的str沒有一點用處。
那么如何修改呢?只需要將GetMemory的參數改為指針的引用 or 指針的指針即可
指針的引用版

void GetMemory1(char* p){p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(str);strcpy(str,"hello");printf(str);
}int main() {Test1();
}

指針的指針版:

void GetMemory1(char** p){*p = (char*)malloc(100);
}
void Test1(void){char* str =NULL;GetMemory1(&str);strcpy(str,"hello");printf(str);
}

再來個題目

char* GetMemory2(){char p[] = "hello";return p;
}
void Test2(){char* str = NULL;str = GetMemory2();printf(str);
}

這會導致系統崩潰,因為
char p[] = “hello”; 是一個局部數組,存儲在上。
當 GetMemory2() 結束后,p 變量的生命周期結束,它所在的棧內存可能被覆蓋或釋放。
str = GetMemory2(); 讓 str 指向了這塊無效的內存。
printf(str); 試圖訪問這塊無效的內存,導致未定義行為(Undefined Behavior),可能程序崩潰。
但如果我們修改為,此時內存被分配到堆上,就不會報錯了。注意還需要對應的free

char* p = (char*)malloc(100);

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

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

相關文章

HBuilder X 使用 TortoiseSVN 設置快捷鍵方法

HBuilder X 使用 TortoiseSVN 設置快捷鍵方法 單文件&#xff1a;(上鎖&#xff0c;解鎖&#xff0c;提交&#xff0c;更新) 安裝好 TortoiseSVN &#xff0c;或者 按圖操作&#xff1a; 1&#xff0c;工具欄中 【自定義快捷鍵】 2&#xff0c;點擊 默認的快捷鍵設置&…

JmeterHttp請求頭管理出現Unsupported Media Type問題解決

JmeterHttp請求頭管理出現Unsupported Media Type問題解決 大多數的app與pc端壓測的時候都會出現這種情況 當我們在jemter測試當中當中遇見Unsupported Media Type&#xff0c;有一種可能就是我們請求的網頁的content-Type的類型與我們測試的時候的類型不一致 解決方法 可以添…

Spring AI 1.0.0-M6 快速開始(一)

Spring AI 1.0.0-M6 入門一、存儲庫二、依賴管理完整maven 入門 Spring 是JAVA中我們經常使用的框架之一&#xff0c;Spring AI不斷的發展迭代目前已經到M6版本據說上半年會出一個穩定版本。 本節提供了如何開始使用Spring AI的M6。 一、存儲庫 1.0 M6 -添加Spring存儲庫 需…

頂點著色器和片段著色器

在Unity渲染中&#xff0c;**頂點著色器&#xff08;Vertex Shader&#xff09;和片段著色器&#xff08;Fragment Shader&#xff09;**是圖形渲染管線中的兩個核心階段。我們可以通過一個比喻來理解它們的分工&#xff1a;想象你要畫一幅由三角形組成的3D模型&#xff0c;頂點…

Impacket工具中的橫向滲透利器及其使用場景對比詳解

在滲透測試中&#xff0c;橫向移動&#xff08;Lateral Movement&#xff09;是指攻擊者在獲得一個系統的控制權限后&#xff0c;通過網絡進一步滲透到其他系統的過程。Impacket 是一款強大的滲透測試工具集&#xff0c;提供了多種實現橫向滲透的腳本&#xff0c;常見的工具包括…

設計模式|策略模式 Strategy Pattern 詳解

目錄 一、策略模式概述二、策略模式的實現2.1 策略接口2.2 具體策略類2.3 上下文類2.4 客戶端代碼2.5 UML類圖2.6 UML時序圖 三、優缺點3.1 ?優點3.2 ? 缺點 四、最佳實踐場景4.1 適合場景描述4.2 具體場景 五、擴展5.1 繼承復用機制和復合策略5.2 對象管理&#xff1a;優化策…

迷你世界腳本顯示板管理接口:DisPlayBoard

顯示板管理接口&#xff1a;DisPlayBoard 迷你世界 更新時間: 2023-04-26 10:21:14 具體函數名及描述如下: 序號 函數名 函數描述 1 showBoard(...) 對玩家顯示顯示板 2 hideBoard(...) 對玩家隱藏顯示板 3 setBoardPicture 對玩家設置顯示板的圖片…

尚硅谷爬蟲note14

一、scrapy scrapy&#xff1a;為爬取網站數據是&#xff0c;提取結構性數據而編寫的應用框架 1. 安裝 pip install scrapy 或者&#xff0c;國內源安裝 pip install scrapy -i https&#xff1a;//pypi.douban.com/simple 2. 報錯 報錯1&#xff09;building ‘twisted.te…

merge函數

merge函數 今天在刷lc&#xff0c;從靈神題解中學到的 來源&#xff1a;560. 和為 K 的子數組 - 力扣&#xff08;LeetCode&#xff09; java8 merge()方法被引入到HashMap類中&#xff0c;用于簡化鍵值對操作&#xff0c;在處理鍵值對時&#xff0c;提供一個重新映射函數來決…

Notepad++ 8.6.7 安裝與配置全攻略(Windows平臺)

一、軟件定位與核心優勢 Notepad 是開源免費的代碼/文本編輯器&#xff0c;支持超過80種編程語言的高亮顯示&#xff0c;相比系統自帶記事本具有以下優勢&#xff1a; 輕量高效&#xff1a;啟動速度比同類軟件快30%插件擴展&#xff1a;支持NppExec、JSON Viewer等200插件跨文…

建筑兔零基礎自學python記錄39|實戰詞云可視化項目——章節分布10(上)

這次我們來制作《紅樓夢》各章節的分布情況&#xff1a; 源代碼&#xff1a; import pandas as pd import numpy as np import matplotlib.pyplot as pltdf_hlm pd.read_csv("hlm.txt", names["hlm_texts"]).dropna()df_hlm df_hlm[~df_hlm.hlm_texts.s…

C++:#ifndef 頭文件保護機制詳解

在C開發中&#xff0c;頭文件可能會被多個源文件包含&#xff0c;導致編譯錯誤。為了避免這種情況&#xff0c;我們使用了頭文件保護機制&#xff08;防止重復包含&#xff09;。 頭文件保護的原理 通過預處理指令#ifndef&#xff08;如果沒有定義&#xff09;和#define&…

利用MQ自動取消未支付超時訂單最佳實踐

一、利用MQ自動取消未支付超時訂單最佳實踐 1、基于 RocketMQ 延遲消息 1.1&#xff1a;延遲消息 當消息寫入到 Broker 后&#xff0c;不會立刻被消費者消費&#xff0c;需要等待指定的時長后才可被消費處理的消息&#xff0c;稱為延時消息。 1.2&#xff1a;實現流程 &am…

基于 ChatGPT 創建專屬 GPTs

文章目錄 基于 ChatGPT 創建專屬 GPTs一、效果展示1.1 中文命名專家1.2 行程小助手 二、核心配置2.1 Instructions2.3 Actions 三、Agent 簡介3.1 功能框架3.2 工作流程3.3 意圖識別 四、數據流程 基于 ChatGPT 創建專屬 GPTs ChatGPT 具備定制 GPTs 的能力&#xff0c;能夠通…

Spring Boot WebFlux 中 WebSocket 生命周期解析

Spring Boot WebFlux 中的 WebSocket 提供了一種高效、異步的方式來處理客戶端與服務器之間的雙向通信。WebSocket 連接的生命周期包括連接建立、消息傳輸、連接關閉以及資源清理等過程。此外&#xff0c;為了確保 WebSocket 連接的穩定性和可靠性&#xff0c;我們可以加入重試…

【數據挖掘】異構圖與同構圖

在圖論&#xff08;Graph Theory&#xff09;中&#xff0c;異構圖&#xff08;Heterogeneous Graph&#xff09;和同構圖&#xff08;Homogeneous Graph&#xff09;是兩種不同的圖結構概念&#xff0c;它們的主要區別在于節點和邊的類型是否單一。 1. 異構圖&#xff08;Hete…

Golang實踐錄:go發布版本信息收集

go發布版本信息收集。 背景 本文從官方、網絡資料收羅有關go的發布歷史概況。主要目的是能快速了解golang不同版本的變更。鑒于官方資料為英文&#xff0c;為方便閱讀&#xff0c;使用工具翻譯成中文&#xff0c;重要特性參考其它資料補充/修改。由于發布版本內容較多&#xf…

【C++】: STL詳解 —— set和map類

目錄 關聯式容器 鍵值對 set set的概念 set的構造函數 set的使用 map map的概念 map的構造函數 map的使用 multiset multimap 關聯式容器 C標準庫提供了多種容器&#xff0c;用于高效管理和操作數據集合。這些容器可分為以下幾類&#xff1a; 順序容器&#xff08;…

DeepSeek:構筑大數據平臺底座的最優解

一、大數據平臺底座的重要性 在數字化浪潮席卷全球的當下,數據已成為企業乃至整個社會最具價值的資產之一 。大數據平臺底座作為數據處理和業務支撐的核心樞紐,其重要性不言而喻,猶如大廈的基石,關乎整個數據生態系統的穩定與發展。 從數據處理角度來看,隨著互聯網、物聯…

Minix OS的配置 SSH C程序編譯

Minix3的下載 官網&#xff1a;https://www.minix3.org/ 安裝 平臺&#xff1a;VMware 開機后進入系統使用setup命令來配置和安裝盡量配置一個DNS服務器&#xff0c;比如8.8.8.8 SSH 安裝&#xff1a;pkgin install openssh 修改配置文件&#xff0c;需要&#xff1a; 修…