1,函數模板缺省情況下都是內聯的? ?需要進一步的學習
- 父類析構函數為非虛函數,子類為虛函數_zhl11a的專欄-CSDN博客_父類的析構函數是非虛的
- 父類析構函數為非虛函數,子類為虛函數? delete子類指針(指向這個子類對象)會調用父類的析構函數
#include <iostream>
using namespace std;class Base
{
public:~Base(){cout<<"~Base()"<<endl;}};class ABase : public Base
{
public:virtual ~ABase(){cout<<"~ABase()"<<endl;}};int main(){Base *pBase = new ABase;delete pBase;//此處出錯getchar();return 0;}
assert斷言?
- assert斷言是用來檢查非法情況而不是錯誤情況的,用來幫開發者快速定位問題的位置。如果表達式為假(0),那么首先向錯誤流strerr打印一條錯誤信息,然后通過abort函數終止程序的運行。NDEBUG宏打開狀態時assert宏是可用的。默認情況下,assert宏只有在Debug版本才起作用,而在Release版本中將被忽略。但在許多操作系統的C程序中,Release版本中也將NDEBUG宏依然為打開狀態。? 斷言不是用于處理錯誤情況的
- 斷言assert函數,C語言assert函數完全攻略
- C/C++ 學習筆記八(斷言與異常處理) - 云+社區 - 騰訊云
類的析構函數可以是虛函數 但是構造函數不可以
- 調用構造函數時還不能確定對象的真實類型(因為子類會調父類的構造函數);而且構造函數的作用是提供初始化,在對象生命期只執行一次,不是對象的動態行為,也沒有太大的必要成為虛函數
- 純虛擬函數是用來提供函數接口的,虛擬函數是用來提供函數接口和默認的函數操作,非虛擬函數是用來提供函數操作的。
- 構造函數,析構函數可不可以是虛函數?_學海無涯-CSDN博客
類中有指向其他資源的指針,且這個資源由類本身進行釋放,那么可以使用編譯系統生成的默認構造函數進行對象的復制
- C++有關拷貝構造函數(默認/淺/深拷貝構造函數) - Hk_Mayfly - 博客園
子類可以訪問父類的保護成員,子類友元類可以通過子類對象去訪問父類的保護成員?
#include <iostream>class father{
protected:int father_protected = 123;
public:int father_public = 456;
};class son : public father{
public:void print_protected(){std::cout << father_protected << std::endl;}void print_public(){std::cout << father_public << std::endl;}int wed = 123;friend class son_friend;
};class son_friend{
public:void friend_print(son son1){
// std::cout << son1.wed << std::endl;
// son1.print_public();son1.print_protected();}
};
int main(){son son1;son1.wed = 456789;son_friend ofo;ofo.friend_print(son1);
}
兩個指針p和q,指向同一個數組,則他們可以進行關系運算,例如p<q,p!=q,指針可以做減法操作,指針可以同整數相加減? 正確
int a[10]={0,1,2,3,4,5,6,7,8,9};int *p = a;int *q = &a[9];std::cout << "p和q之間的距離是:" << q-p << std::endl;std::cout << "在p的基礎上移動 8個距離后的數值為:" << *(p+8) << std::endl;
判斷以下定義是否正確? 錯誤
- 使用const進行修飾 因此在函數的內部 不可以對元素進行修改,去掉const 編譯通過
class Date{
private:int d,m,y;
public:int year() const {return y++;};
};
const 成員函數
- ? 如果不使用const修飾符 就會造成對于函數的返回數組進行修改
class A{
private:int data;
public:A(int num):data(num){};~A(){};int& get_data(){return data;}
};int main(){A a(1);a.get_data() = 4;std::cout << a.get_data() << std::endl;
}
- 使用const進行限定? 阻止對于參數的修改
class A{
private:int data;
public:A(int num):data(num){};~A(){};const int& get_data(){return data;}
};int main(){A a(1);
// a.get_data() = 4;// 不允許std::cout << a.get_data() << std::endl;
}
class A{
private:int data;
public:A(int num):data(num){};~A(){};int& get_data(){return data;}
};int main(){const A a(1);
// a.get_data() = 4;// 不允許get_data(a);//錯誤std::cout << a.get_data() << std::endl;
}
- ?a 是一個const 對象, 它調用了 get_data 方法,所以函數簽名應該是: get_data(a){} 而 a是一個 const 對象, 我們默認的 this 指針并不是 const 類型,所以參數類型不匹配, 編譯無法通過! 這下我們終于清楚了, const 修飾成員函數, 根本上是修飾了 this 指針。
-
補充一點,如果成員函數同時具有 const 和 non-const 兩個版本的話, const 對象只能調用const成員函數, non-const 對象只能調用 non-const 成員函數。
- 梳理c++ const 修飾函數 - 知乎
子類沒有定義構造函數,則調用父類的無參數的構造方法,否則不調用父類無參構造函數
- 在C++中子類繼承和調用父類的構造函數方法_菜頭-CSDN博客_c++子類構造函數調用父類構造函數
- 子類可以繼承父類所有的成員變量和成員方法,但不繼承父類的構造方法,因此,在創建子類對象時,為了初始化從父類繼承來的數據成員,系統需要調用其父類的構造方法
- 如果沒有顯式的構造函數,編譯器會給一個默認的構造函數,并且該默認的構造函數僅僅在沒有顯式地聲明構造函數情況下創建
- 如果子類沒有定義構造方法,則調用父類的無參數的構造方法
- 如果子類定義了構造方法,不論是無參數還是帶參數,在創建子類的對象的時候,首先執行父類無參數的構造方法,然后執行自己的構造方法
- 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數,則會調用父類的默認無參構造函數
- 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類自己提供了無參構造函數,則會調用父類自己的無參構造函數
- 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類只定義了自己的有參構造函數,則會出錯(如果父類只有有參數的構造方法,則子類必須顯示調用此帶參構造方法)
- 如果子類調用父類帶參數的構造方法,需要用初始化父類成員對象的方式
// 子類無構造方法 則調用父類的無參數的構造方法
class father_1{
public:father_1(){std::cout << "father 1 create!\n";}
};class children_1 : public father_1{};
int main(){children_1 children1;
}
//子類定義了構造函數 則先調用父類的構造函數 再次調用子類的構造函數
class father_1{
public:father_1(){std::cout << "father 1 create!\n";}
};class children_1 : public father_1{
public:children_1(){std::cout << "children_1 create!\n";}
};
int main(){children_1 *child = new children_1();}
虛函數是可以內聯的嗎?可以減少函數調用的開銷,提高效率
- C++面試題:虛函數(virtual)可以是內聯函數(inline)嗎?_changyi9995的博客-CSDN博客
- 虛函數可以是內聯函數,內聯是可以修飾虛函數的,但是當虛函數表現多態性的時候不能內聯。
- 內聯是在發生在編譯期間,編譯器會自主選擇內聯,而虛函數的多態性在運行期,編譯器無法知道運行期調用哪個代碼,因此虛函數表現為多態性時(運行期)不可以內聯。?
inline virtual
唯一可以內聯的時候是:編譯器知道所調用的對象是哪個類(如?Base::who()
),這只有在編譯器具有實際對象而不是對象的指針或引用時才會發生。
class Base{
public:inline virtual void who(){std::cout << "I am Base\n";}virtual ~Base();
};class Derived : public Base{
public:inline void who(){std::cout << "I am Derived\n";}
};
int main(){// 此處的虛函數 who(),是通過類(Base)的具體對象(b)來調用的,// 編譯期間就能確定了,所以它可以是內聯的,但最終是否內聯取決于編譯器。Base b;b.who();// 此處的虛函數是通過指針調用的,呈現多態性,需要在運行時期間才能確定,// 所以不能為內聯。Base *ptr = new Derived();ptr->who();// 因為Base有虛析構函數(virtual ~Base() {}),//所以 delete 時,會先調用派生類(Derived)析構函數,//再調用基類(Base)析構函數,防止內存泄漏。delete ptr;ptr = nullptr;}
- 鏈接給的例子 將析構函數定義為虛函數,但是會出錯,除了刪除的方式以外,還可以將其定義為default的方式
- ?virtual ~Base() = default;
class Base{
public:inline virtual void who(){std::cout << "I am Base\n";}virtual ~Base() = default;
};class Derived : public Base{
public:inline void who(){std::cout << "I am Derived\n";}
};
int main(){// 此處的虛函數 who(),是通過類(Base)的具體對象(b)來調用的,// 編譯期間就能確定了,所以它可以是內聯的,但最終是否內聯取決于編譯器。Base b;b.who();// 此處的虛函數是通過指針調用的,呈現多態性,需要在運行時期間才能確定,// 所以不能為內聯。Base *ptr = new Derived();ptr->who();// 因為Base有虛析構函數(virtual ~Base() {}),//所以 delete 時,會先調用派生類(Derived)析構函數,//再調用基類(Base)析構函數,防止內存泄漏。delete ptr;ptr = nullptr;}
C++命名空間必須要指定名字 錯誤 可以
- C++/C++11中命名空間(namespace)的使用_網絡資源是無限的-CSDN博客_c++ namespace
- 未命名的命名空間(unnamed namespace):是指關鍵字namespace后緊跟花括號括起來的一系列聲明語句。未命名的命名空間中定義的變量擁有靜態生命周期:它們在第一次使用前創建,并且直到程序結束才銷毀。
- ?一個未命名的命名空間可以在某個給定的文件內不連續,但是不能跨越多個文件。每個文件定義自己的未命名的命名空間,如果兩個文件都含有未命名的命名空間,則這兩個空間互相無關。如果一個頭文件定義了未命名的命名空間,則該命名空間中定義的名字將在每個包含了該頭文件的文件中對應不同實體。和其它命名空間不同,未命名的命名空間僅在特定的文件內有效,其作用范圍不會橫跨多個不同的文件。
一個類可以有多個構造函數 但是只能有一個析構函數
- 理一理C++的構造函數 - 知乎
二叉樹的前序、中序后續遍歷 常常使用遞歸的方式來實現
- 二叉樹遍歷的遞歸實現詳解(先序、中序、后序和層次遍歷) - violet-evergarden - 博客園
友元函數破壞了類的封裝性
#include機制用于將源程序片段收集在一起,形成一個完整的編譯單元作為編譯器的輸入。
- C++筆記(隨時更新)_小明喜歡寫bug的博客-CSDN博客? 163條
關于純虛函數 說法正確的是
- 具有純虛函數的類稱為虛基類 錯誤 虛基類是指虛繼承的基類,主要解決的是從不同路徑多次繼承同一個基類的問題,與純虛函數無關
- 具有純虛函數的類不能創建類對象? 正確
- 一個基類說明有純虛函數,其派生類一定要實現該純虛函數? 錯誤 可以不實現純虛函數,那么子類也將作為 純虛類
- 純虛函數是一種特殊的虛函數 他是個空函數? 錯誤 ,空函數是指不執行任何語句直接返回的函數,顯然純虛函數不滿足
- 純虛函數是一種特殊的虛函數,它是個空函數_百度知道
選擇正確的語句是:?
int main(){char* pBuf = new char(20);sprintf(pBuf,"%s","This is a test.\n");printf("%s",pBuf);delete pBuf;
};
編譯過程中處理#include的語句的階段是??
- 預編譯? 感覺是預編譯階段,但是沒有找到明確的答案
- 語法分析
- 詞法分析
- 二進制代碼
錯誤的賦值表達式
int mian(){int a[10];int*p = nullptr;//賦值表達式的位置p = &a;//錯誤,因為a就代表了地址 即 a的含義等效于a[0]p = &a[0];*p = 1;p = a;}
? 設置虛基類的目的是為了
- 消除二義性
- 設置虛基類的目的是(__牛客網
多重繼承定義:
- 一個派生類(D)有2個或2個以上的基類(B和C);
- 多重繼承引起的二義性:
- 假如上述這些基類(B和C)具有相同的基類A,A中的成員數據和成員函數,最終都會以雙份的形式拷貝到類D中,
- 那么調用的時候就會出現二義性問題。
虛基類:
- 專門用來解決多重繼承引起的二義性問題;(可以理解為D直接從A繼承)
- 虛基類的具體實現的注意細節有很多,這里不再列舉了,我認為只需要了解原理即可。
下列常量定義正確的是
const int VERSION = 200;const int g_xx[4] = {1,2,4,8};const char* const hh = "Hello world";
不確定enum Color{BLUE,RED};const enum Color gg =BLUE;
const enum Color gg =BLUE;
// gg = RED; //錯誤 被const修飾,不可以更改const char* const hh = "Hello world";
?關于命名空間的理解正確的是? 搜查?
- 通過使用聲明引入的元素名字會遮蔽名字相同的非局部聲明
- 表達式::a 一般表示引用全局作用域中聲明的元素a
- 使用關鍵字namespace定義的命名空間必須要有顯示的名字必須是獨一無二的 錯誤,可以不需要顯示的名字
- 名字空間是可以嵌套的? ?
繼承 和訪問之間的關系
- C++繼承:公有,私有,保護 - csqlwy - 博客園
程序執行后會有錯誤或者什么效果?
- 數組訪問越界會出現什么情況?棧溢出
- 堆棧溢出就是不顧堆棧中數據塊大小,向該數據塊寫入了過多的數據,導致數據越界,結果覆蓋了老的堆棧數據。
- c/c++ 棧溢出、越界、泄漏_kevin的博客-CSDN博客_c++棧溢出
- 【堆棧和棧溢出】MSP430?數組填充越界引起的棧溢出?導致程序跑飛 - bandaoyu - 博客園
- Address Sanitizer 用法 - 簡書? ? ? 重點
#include <iostream>
#include <vector>#define MAX 255
int main(){
// unsigned char A[MAX];
// for (int i = 0; i <= MAX+8; ++i) {
// A[i] = 'c';
// }unsigned char j = 'a';std::vector<char>temp(MAX,'\0');for (int i = 0; i <= MAX; ++i) {temp.at(i) = j;}for (int j = 0; j <= MAX; ++j) {std::cout << temp[j] << " ";}
}
關于動態庫和靜態庫的說法 正確的是
- 程序運行的時候不需要靜態庫 正確
- 靜態庫在程序編譯的時候會被連接到目標代碼中 錯誤,靜態庫編譯的時候會被直接拷貝,動態庫是被鏈接
- 動態庫在程序運行時才被載入? 正確
- 動態庫 在程序編譯的時候不會被連接到目標代碼? 錯誤
補充
- 庫是一段編譯好的二進制的代碼,加上頭文件供別人進行調用
- 使用庫 的場景:1,不希望別人看到源碼,以庫的方式進行封裝,只需要暴露頭文件;減少編譯的時間,因為庫是已經編譯好的二進制的代碼,編譯的時候只需要簡單的的link,不需要浪費編譯的時間
靜態庫
- windows下是lib,linux下是.a,靜態庫在編譯的時候會被直接拷貝一份,復制到目標代碼里面,這段代碼在目標程序里面就不會被改變了;靜態庫的好處是 編譯完成之后庫文件就不會有作用了,目標程序沒有外部依賴,直接就可以運行,缺點就是使得目標體積變大
動態庫
- 動態鏈接庫,win下是dll,linux下是so,mac下是dylib。動態庫在編譯的時候不會被拷貝到目標程序中,目標程序只會存儲動態庫的引用。只有程序運行的時候才會被加載;動態庫不需要拷貝到目標程序中,不會影響目標程序的體積,同一份庫文件可以被多個程序共用。編譯才會被載入的特性,因此隨時可以對其進行替換。但是 動態加載會帶來性能的損耗,使用動態庫很依賴外部的環境,缺庫會導致程序無法運行。
參考鏈接
- 靜態庫與動態庫的區別_sheng_bin的博客-CSDN博客_動態庫和靜態庫的區別
const 和 宏 的區別
- 宏缺少類型檢查,const具備嚴格的類型審查? 正確
- 宏在編譯鏈接和運行的時候沒有符號,const常量在編譯和調試的時候(打開編譯器調試開關)可見
- 宏定義在函數的內部,函數作用域結束后仍然可用,const常量只在作用域內可見
- 宏在編譯階段展開? const常量在編譯階段處理? 錯誤;宏在預處理階段,const變量在編譯階段進行處理
?C++類不占據內存 只有實例化對象之后才會占據內存
- c++關于類到底占不占內存的問題,書上說類是不占內存的,對象時占內存的。_百度知道
C++語言中提供了哪些代碼重用的方式()
- 繼承
- 多態
- 模板
關于運算符重載,下列說法不正確的是
- 重載時, 運算符的操作個數可以改變? 錯誤
- 重載時,操作符的優先級可以改變? 錯誤
- 重載時,運算符號的功能可以改變? 正確
- 重載時,運算符號的結合性可以改變? 錯誤
注意事項
- 不是所有的運算符號都可以被重載
- 重載運算符號 不可以改變其優先級和結合性
- 重載不會改變運算符的用法,原有的操作數、操作數在左邊還是在右邊都不會被改變
- 運算符重載不能有默認的參數
- 運算符重載既可以作為類的成員函數,也可以作為全局函數
- 箭頭運算符->、下標運算符[?]、函數調用運算符(?)、賦值運算符=只能以成員函數的形式重載
- 有關運算符重載正確的描述是()。 ?__牛客網
虛函數說法正確的是
- 成員函數被聲明為虛函數之后,其派生類的同名函數都自動轉換成 虛函數? 正確
- 虛函數不可以有函數體? 錯誤??純虛函數在函數可以擁有函數體,但是類中只可以寫純虛函數的聲明,純虛函數的定義必須寫在類外
- 通常,如果一個類可以被繼承,構造函數和析構函數都有必要被定義為虛函數。錯誤,析構函數一般可以被定義成虛函數,但是構造函數是絕對不可以被定義為虛函數
- 虛函數在基類中可不實現,但是派生類中必須實現? 錯誤 派生類也可以不實現
- 我難道不配擁有函數體嗎?---【純虛函數函數體】_Alice_lihao的博客-CSDN博客