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ù)中不要拋出異常
