67_經(jīng)典問題解析五

1. 面試題:編寫程序判斷一個變量是不是指針。

拾遺

  • C++中仍然支持C語言中的可變參數(shù)函數(shù)
  • C++編譯器的匹配調(diào)用優(yōu)先級
    (1) 重載函數(shù)
    (2) 函數(shù)模板
    (3) 變參函數(shù)

思路:
將變量分為兩類:指針 vs 非指針
編寫函數(shù):
指針變量調(diào)用時返回true
非指針變量調(diào)用時返回false
通過函數(shù)模板變參函數(shù)的結(jié)合:

編程說明:指針判斷解決方案初步嘗試

#include <iostream>
#include <string>

using namespace std;

class Test
{
public:
    Test()
    {
    }
    
    virtual ~Test()
    {
    }
};

template
<typename T>
bool IsPtr(T* t)
{
    return true;
}

bool IsPtr(...)
{
    return false;
}

int main()
{
    int i = 0;
    int* p = &i;
    
    cout << "p is a pointer : " << IsPtr(p) << endl;
    cout << "i is NOT a pointer : " << IsPtr(i) << endl;
    
    Test t;
    Test* pt = &t;
    
    cout << "pt is a pointer : " << IsPtr(pt) << endl;
//  cout << "t is NOT a pointer : " << IsPtr(t) << endl;        // error
    
    return 0;
}

輸出結(jié)果:

p is a pointer : 1
i is NOT a pointer : 0
pt is a pointer : 1

存在問題:IsPtr(t)報錯:cannot pass objects of non-trivially-copyable type ‘class Test’ through ‘...’
問題分析:變參函數(shù)源自于C語言,是否支持對象的解析。
進一步優(yōu)化:如何讓編譯器精確匹配函數(shù),但不進行實際的調(diào)用?

編程說明:指針判斷解決方案完成版

#include <iostream>
#include <string>

using namespace std;

class Test
{
public:
    Test()
    {
    }
    
    virtual ~Test()
    {
    }
};

template
<typename T>
char IsPtr(T* t)
{
    return 'd';
}

int IsPtr(...)
{
    return 0;
}

// sizeof是編譯器內(nèi)置指示符,因此,下面的 == 在編譯期就會完成
#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 NOT a pointer : " << ISPTR(i) << endl;
    
    Test t;
    Test* pt = &t;
    
    cout << "pt is a pointer : " << ISPTR(pt) << endl;
    cout << "t is NOT a pointer : " << ISPTR(t) << endl;        // error
    
    return 0;
}

輸出結(jié)果:

p is a pointer : 1
i is NOT a pointer : 0
pt is a pointer : 1
t is NOT a pointer : 0

2. 面試題:如果構(gòu)造函數(shù)中拋出異常會發(fā)生什么情況?

構(gòu)造函數(shù)中拋出異常:
(1) 構(gòu)造過程立即停止
(2) 當前對象無法生成
(3) 析構(gòu)函數(shù)不會被調(diào)用
(4) 對象所占的空間立即收回

工程項目中的建議:
(1) 不要在構(gòu)造函數(shù)中拋出異常
(2) 當構(gòu)造函數(shù)可能產(chǎn)生異常時,使用二階構(gòu)造模式

編程說明:構(gòu)造中的異常

#include <iostream>
#include <string>

using namespace std;

class Test
{
public:
    Test()
    {
        cout << "Test()" << endl;
        throw 0;
    }
    
    virtual ~Test()
    {
        cout << "virtual ~Test()" << endl;
    }
};

int main()
{
    Test* p = reinterpret_cast<Test*>(1);
    
    cout << "p = " << p << endl;
    
    try
    {
        p = new Test();
    }
    catch(...)
    {
        cout << "Exception ..." << endl;
    }
    
    return 0;
}

輸出結(jié)果:

p = 0x1
Test()
Exception ...

3. 面試題:析構(gòu)函數(shù)中拋出異常會發(fā)生什么情況?

析構(gòu)函數(shù)的異常將導致:對象所使用的資源無法完全釋放。
因此:避免在析構(gòu)函數(shù)中拋出異常

4. 小結(jié)

  • C++中依然支持變參函數(shù)
  • 變參函數(shù)無法很好的處理對象參數(shù)
  • 利用函數(shù)模板變參函數(shù)能能夠判斷指針變量
  • 構(gòu)造函數(shù)和析構(gòu)函數(shù)中不要拋出異常
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容