某日二師兄參加XXX科技公司的C++工程師開發崗位第14面: > 面試官:在C++中,有哪些可執行體? > > 二師兄:可執行體? > > 面試官:也就是可調用對象。 > > 二師兄:讓我想一想。函數、函數指針、類的靜態方法、類的成員方法、仿函數、lambda表達式。 > > 面試官:能說一說他們之 ...
某日二師兄參加XXX科技公司的C++工程師開發崗位第14面:
面試官:在C++中,有哪些可執行體?
二師兄:可執行體?
面試官:也就是可調用對象。
二師兄:讓我想一想。函數、函數指針、類的靜態方法、類的成員方法、仿函數、lambda表達式。
面試官:能說一說他們之間有什麼區別嗎?
二師兄:好的。函數是一段代碼,執行特定任務,接受參數並返回值。
int add(int a, int b)
{
return a + b;
}
二師兄:函數指針是指向函數的指針。
int add(int a, int b)
{
return a + b;
}
using addptr = int(*)(int,int);
addptr ptr = &add; //函數指針
int sum = addptr(1,2);
二師兄:類的靜態方法和函數基本一致,只不過此靜態方法屬於整個類所有。而成員方法則只能通過類的實例來調用。
class Foo
{
public:
static int add(int a, int b) { return a + b;} //靜態方法
int add2(int a, int b) { return a + b; } //成員方法
};
int sum1 = Foo::add(1,2);
Foo f;
int sum2 = f.add2(2,1);
二師兄:仿函數是一個類或結構體,重載了
()
運算符。
struct Add
{
int operator()(int a, int b) { return a+ b;}
};
int sum = Add()(1,2);
二師兄:
lambda
表達式在C++11時被引入,本質上是是一個匿名函數。
auto add = [](int a, int b) {return a + b;};
int sum = add(1,2);
//or
int a =1 , b = 2;
auto ladd = [a,b](){return a + b;};
int sum = ladd();
面試官:你知道
std::function
?二師兄:哦,這個標準也是在C++11引入的,它的對象可以把以上所說的可執行體保存起來。
std::function<int(int,int)> add_fun;
add_fun = add;
add_fun = ptr;
add_fun = Foo::add;
add_fun =std::bind(&Foo::add2,&f,std::placeholders::_1,std::placeholders::_2);
add_fun = Add();
add_fun = ladd;
面試官:那你知道以上可執行體之間的性能有何差別嗎?
二師兄:額,性能應該差不多吧。。
面試官:好的,回去等通知吧。
今日二師兄的表現不錯,讓我們看一下麵試官的最後一個問題:
知道以上可執行體之間的性能有何差別嗎?
從性能上講,函數、類的靜態/成員方法(非虛方法)、仿函數和lambda
表達式的性能基本相同,而函數指針和std::function
的性能要差一些。因為函數指針和std::function
的實例沒有辦法被內聯。
好了,今日份面試到這裡就結束了。 讓我們一起期待明天二師兄的表現吧。
關註我,帶你21天“精通”C++!(狗頭)