[英]Default value of a function pointer in C++
C ++中函數指針的默認值是什么? (顯然它不能是NULL
,所以它是什么?)
這個程序應該如何表現?為什么?
struct S { void (*f)(); };
int main()
{
S s = S();
s.f(); // What is the value of s.f?
}
首先任何指針都可以為null。 這是關於指針的一個普遍真理。 也就是說,你的將是空的,但不一定是你想的原因;
C ++11§8.5,p10
初始值為空集括號的對象,即() ,應進行值初始化 。
這很重要,因為您的聲明包括:
S s = S();
通過值初始化的定義:
C ++11§8.5,p7
對值類型T的對象進行值初始化意味着:
如果T是具有用戶提供的構造函數(12.1)的(可能是cv限定的)類類型(第9節),則調用T的默認構造函數(如果T沒有可訪問的默認構造函數,則初始化是錯誤的) ;
如果T是一個(可能是cv限定的)非聯合類類型而沒有用戶提供的構造函數,那么該對象是零初始化的 ,如果T的隱式聲明的默認構造函數是非平凡的,則調用該構造函數。
如果T是數組類型,那么每個元素都是值初始化的;
否則,該對象被零初始化。
這讓我們了解了對象類型被零初始化的意義:
C ++11§8.5,p5
零初始化T類型的對象或引用意味着:
如果T是標量類型(3.9),則將對象設置為值0(零),作為整數常量表達式,轉換為T (103)
如果T是(可能是cv限定的)非聯合類類型,則每個非靜態數據成員和每個基類子對象都是零初始化的,並且填充初始化為零位;
如果T是(可能是cv限定的)並集類型,則對象的第一個非靜態命名數據成員將進行零初始化,並將填充初始化為零位;
如果T是數組類型,則每個元素都是零初始化的;
如果T是引用類型,則不執行初始化。
103)如4.10中所述,將值為0的整型常量表達式轉換為指針類型會產生空指針值 。
后者是你指針為空的原因。 它不會得到保證 - 所以給定相同代碼的標准,但是將s
的聲明更改為:
S s;
鑒於上述聲明,標准采用了不同的路徑:
C ++11§8.5,p11
如果沒有為對象指定初始化程序,則默認初始化該對象; 如果未執行初始化,則具有自動或動態存儲持續時間的對象具有不確定的值。 [注意:具有靜態或線程存儲持續時間的對象是零初始化的,請參見3.6.2。
然后討論最后一個問題,什么是默認初始化 :
C ++11§8.5,p6
默認初始化T類型的對象意味着:
如果T是一個(可能是cv限定的)類類型(第9節),則調用T的默認構造函數(如果T沒有可訪問的默認構造函數,則初始化是錯誤的);
如果T是數組類型,則每個元素都是默認初始化的;
否則,不執行初始化。
在您的情況下,對象s
是零初始化的,這意味着函數指針為NULL
。
struct S { void (*f)(); };
int main()
{
S s = S();
if ( s.f == NULL)
std::cout << "s.f is NULL" << std::endl;
}
輸出:
s.f is NULL
在線演示 。
函數指針可以為NULL,這樣就可以表明它們沒有指向任何東西!
函數指針可以為NULL,您可以為其指定NULL。 看看這里例如:
#include <iostream>
using namespace std;
struct S { void (*f)(); };
int main()
{
S s = S();
s.f = NULL;
return 0;
}
我相信你調用結構的構造函數的方式(with ()
),f將是NULL。
在C ++(和C)中,指針(不論類型) 本身沒有默認值; 他們接受當時記憶中發生的事情。 但是,它們的默認初始值為NULL
。
當您沒有顯式定義構造函數時,C ++將在每個成員變量上調用默認初始化函數,這將初始化指向0
指針。 但是,如果定義構造函數,但未設置指針的值,則它沒有默認值。 整數,浮點數和雙精度數的行為相同。
在旁邊
int main()
{
S s = S();
s.f(); // <-- This is calling `f`, not getting the pointer value.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.