C ++中函数指针的默认值

时间:2013-02-12 09:20:50

标签: c++ function-pointers

C ++中函数指针的默认值是什么? (显然它不能是NULL,所以它是什么?)

这个程序应该如何表现?为什么?

struct S { void (*f)(); };

int main()
{
    S s = S();
    s.f();   // What is the value of s.f?
}

5 个答案:

答案 0 :(得分:18)

首先任何指针都可以为空。这是关于指针的一个普遍真理。也就是说,你的为空,但不一定是你想到的原因;

  

C ++11§8.5,p10

     

一个对象,其初始化程序是一组空的括号,即(),应为值初始化

这很重要,因为您的声明包括:

S s = S();

通过值初始化的定义:

  

C ++11§8.5,第7页

     

对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,第11页

     

如果没有为对象指定初始值设定项,则该对象为默认初始化;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。 [注意:具有静态或线程存储持续时间的对象为零初始化,请参见3.6.2。

然后回答最后一个问题,什么是默认初始化

  

C ++11§8.5,p6

     

默认初始化T类型的对象意味着:

     
      
  • 如果T是(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

  •   
  • 如果T是数组类型,则每个元素都是默认初始化的;

  •   
  • 否则,不执行初始化。

  •   

答案 1 :(得分:6)

在您的情况下,对象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

Online demo

答案 2 :(得分:3)

函数指针可以为NULL,这样就可以表明它们没有指向任何东西!

答案 3 :(得分:3)

函数指针可以为NULL,您可以为其指定NULL。例如,看一下here

#include <iostream>

using namespace std;

struct S { void (*f)(); };

int main()
{
    S s = S();
    s.f = NULL;
    return 0;
}

我相信你调用结构的构造函数(用()),f的方式将为NULL。

答案 4 :(得分:0)

在C ++(和C)中,指针(不论类型)本身没有默认值 ;他们接受当时记忆中发生的事情。但是,它们的默认初始值为NULL

默认初始化

如果没有明确定义构造函数,C ++将在每个成员变量上调用默认初始化函数,这将初始化指向0的指针。但是,如果定义构造函数,但未设置指针的值,则它没有默认值。整数,浮点数和双精度数的行为相同。

<强>除了

int main()
{
    S s = S();
    s.f();   // <-- This is calling `f`, not getting the pointer value.
}