題目一:
static和const都可以修飾一個類的成員函數,請問:能不能同時用static和const修飾類的成員函數?
const的位置是在函數後邊,修飾一個類的成員函數是寫在函數的最後,而不是前邊。前邊的只是限制了返回值類型。
分析:答案是不能的。C++編譯器在實現const的成員函數的時候爲了確保該函數不能修改類的實例的狀態,會在函數中添加一個隱式的參數const this*。但當一個成員爲static的時候,該函數是沒有this指針的。也就是說此時static的用法和static是衝突的。static的作用是表示該函數只作用在類型的靜態變量上,與類的實例沒有關係;而const的作用是確保函數不能修改類的實例的狀態,與類型的靜態變量沒有關係。因此不能同時用它們。
題目二:
運行下面代碼,輸出的結果是:
class A
{
private:
int m;
public:
A(int a)
{
m=a;
}
void print1()
{
printf("Hello world");
}
void print2()
{
printf("%d",m);
}
};
main函數
int main(int argc, const char * argv[]) {
A* P=NULL;
P->print1();
P->print2();
return 0;
}
運行結果會崩潰。
分析:答案是print1調用正常,打印出Hello world,但運行至print2時,程序崩潰。調用print1時,並不需要P的地址,因爲print1的函數地址是固定的。編譯器會給print1傳入一個this指針,該指針爲NULL,但在print1中該this指針並沒有用到。只要程序運行時沒有訪問不該訪問的內存就不會出錯,因此運行正常。在運行print2時,需要this指針才能得到m_value的值。由於此時this指針爲NULL,因此程序崩潰了。
題目三:
運行下面代碼,輸出的結果是:
class A
{
private:
int m;
public:
A(int a)
{
m=a;
}
void print1()
{
printf("Hello world");
}
virtual void print2()
{
printf("%d",m);
}
};
main函數
int main(int argc, const char * argv[]) {
A* P=NULL;
P->print1();
P->print2();
return 0;
}
程序崩潰分析:print1就不用多說,和上邊的一樣。當調用虛函數print2的時候,要根據實例(即this指針指向的實例)中虛函數表指針得到虛函數表,再從虛函數表中找到函數的地址。由於這一步需要訪問實例的地址(即this指針),而此時this指針爲空指針,因此導致內存訪問出錯。