日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【C++】 67_经典问题分析 五

發(fā)布時(shí)間:2025/3/17 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++】 67_经典问题分析 五 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

面試問(wèn)題 一

編寫(xiě)程序判斷一個(gè)變量是不是指針

指針的判別

  • 拾遺

    • C++ 中仍然支持 C 語(yǔ)言中的可變函數(shù)參數(shù)
    • C++ 編譯器的匹配調(diào)用優(yōu)先級(jí)

    • 重載函數(shù)
    • 函數(shù)模板
    • 變參函數(shù)

  • 思路

    • 將變量分為兩類: 指針 VS 非指針
    • 編寫(xiě)函數(shù):

      • 指針變量調(diào)用時(shí)返回 true
      • 非指針變量調(diào)用時(shí)返回 false

  • 函數(shù)模板與變參函數(shù)的化學(xué)反應(yīng)
template < typename T > bool IsPtr(T* v) // match pointer {return true; }bool IsPtr(...) // match non-pointer {return false; }

編程實(shí)驗(yàn): 指針判斷

#include <iostream>using namespace std;class Test { public:Test(){};virtual ~Test(){}; };template < typename T > bool IsPtr(T* v) // match pointer {return true; }bool IsPtr(...) // match non-pointer {return false; }int main() {int i = 0;int* p = &i;cout << "p is a pointer: " << IsPtr(p) << endl;cout << "i is a pointer: " << IsPtr(i) << endl;Test t;Test* pt = &t;cout << "pt is a pointer: " << IsPtr(pt) << endl;cout << "t is a pointer: " << IsPtr(t) << endl; // 注意這里!對(duì)象傳入變參函數(shù)return 0; } 編譯輸出: test.cpp: In function ‘int main()’: test.cpp:40: warning: cannot pass objects of non-POD type ‘class Test’ through ‘...’; call will abort at runtime運(yùn)行輸出: p is a pointer: 1 i is a pointer: 0 pt is a pointer: 1 非法指令
  • 存在的缺陷:

    • 變參函數(shù)無(wú)法解析對(duì)象參數(shù),可能造成程序崩潰!!

  • 進(jìn)一步的挑戰(zhàn):

    • 如何讓編譯器精準(zhǔn)匹配函數(shù),但不進(jìn)行實(shí)際的調(diào)用?

編程實(shí)驗(yàn): 指針判斷改進(jìn)

#include <iostream>using namespace std;class Test { public:Test(){};virtual ~Test(){}; };template < typename T > char IsPtr(T* v) // match pointer {return 'd'; }int IsPtr(...) // match non-pointer {return 0; }#define ISPTR(p) (sizeof(IsPtr(p)) == sizeof(char)) // 注意這里!int main() {int i = 0;int* p = &i;cout << "p is a pointer: " << ISPTR(p) << endl;cout << "i is a pointer: " << ISPTR(i) << endl;Test t;Test* pt = &t;cout << "pt is a pointer: " << ISPTR(pt) << endl;cout << "t is a pointer: " << ISPTR(t) << endl;return 0; } 輸出:【無(wú)警告,無(wú)錯(cuò)誤】 p is a pointer: 1 i is a pointer: 0 pt is a pointer: 1 t is a pointer: 0

分析: sizeof(IsPtr(t)) 發(fā)生了什么?

  • sizeof 是編譯器的內(nèi)置指示符;
  • 在編譯過(guò)程中所有的 sizeof 將被具體的數(shù)值所替換;
  • 程序的執(zhí)行過(guò)程與 sizeof 沒(méi)有任何關(guān)系;

編譯器根據(jù)匹配規(guī)則匹配到具體的函數(shù) int IsPtr(...);
sizeof(IsPtr(t)); 編譯器將計(jì)算函數(shù)返回值類型所占用的大小;
使用計(jì)算出的數(shù)值整體替換 sizeof(IsPtr(t)),因此不會(huì)發(fā)生實(shí)際的運(yùn)行調(diào)用。
不會(huì)出現(xiàn)變參函數(shù)解析對(duì)象參數(shù)而出現(xiàn)的程序運(yùn)行時(shí)錯(cuò)誤。

面試問(wèn)題 二

如果構(gòu)造函數(shù)中拋出異常會(huì)發(fā)生什么情況呢?

構(gòu)造中的異常

  • 構(gòu)造函數(shù)中拋出異常

    • 構(gòu)造過(guò)程立即停止
    • 當(dāng)前對(duì)象無(wú)法生成
    • 析構(gòu)函數(shù)不會(huì)被調(diào)用
    • 對(duì)象所占用的空間立即收回

  • 工程中的建議

    • 不要在構(gòu)造函數(shù)中拋出異常
    • 當(dāng)構(gòu)造函數(shù)可能產(chǎn)生異常時(shí),使用二階構(gòu)造模式

編程實(shí)驗(yàn): 構(gòu)造中的異常

#include <iostream>using namespace std;class Test { public:Test(){cout << "Test() begin ..." << endl;throw 0;cout << "Test() end ..." << endl;}virtual ~Test(){cout << "~Test()" << endl;} };int main() {Test* p = reinterpret_cast<Test*>(1);cout << "p = " << p << endl;try{p = new Test();}catch(...){cout << "Exception..." << endl;}cout << "p = " << p << endl;return 0; } 輸出: p = 0x1 Test() begin ... Exception... p = 0x1注意: "Test() end ..." 沒(méi)有打印 ==> 證明構(gòu)造過(guò)程停止; "~Test()" 沒(méi)有打印 ==> 證明析構(gòu)函數(shù)不會(huì)被調(diào)用; p 的值沒(méi)有發(fā)生改變 ==> 證明對(duì)象沒(méi)有生成;

內(nèi)存分析:

g++ -g test.cpp valgrind --tool=memcheck --leak-check=full ./a.out

輸出:對(duì)象所占用的內(nèi)存空間被收回

==28776== HEAP SUMMARY: ==28776== in use at exit: 0 bytes in 0 blocks ==28776== total heap usage: 2 allocs, 2 frees, 104 bytes allocated ==28776== ==28776== All heap blocks were freed -- no leaks are possible

析構(gòu)中的異常

  • 避免在析構(gòu)函數(shù)中拋出異常!!
  • 析構(gòu)函數(shù)的異常將導(dǎo)致: 對(duì)象所使用的資源可能無(wú)法完全釋放

編程實(shí)驗(yàn): 析構(gòu)中的異常

#include <iostream>using namespace std;class Test { private:int* m_pointer; public:Test(){cout << "Test()" << endl;m_pointer = new int(0);}virtual ~Test(){cout << "~Test() begin ..." << endl;throw 0;delete m_pointer;cout << "~Test() end ..." << endl;} };int main() {try{Test();}catch(...){cout << "Exception..." << endl;}return 0; } 輸出: Test() ~Test() begin ... Exception...

小結(jié)

  • C++ 中依然支持變參函數(shù)
  • 變參函數(shù)無(wú)法很好的處理對(duì)象參數(shù)
  • 利用函數(shù)模板和變參函數(shù)能夠判斷指針變量
  • 構(gòu)造函數(shù)和析構(gòu)函數(shù)中不要拋出異常

以上內(nèi)容參考狄泰軟件學(xué)院系列課程,請(qǐng)大家保護(hù)原創(chuàng)!

總結(jié)

以上是生活随笔為你收集整理的【C++】 67_经典问题分析 五的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。