C++函数带默认值的几种情形

1. 默认参数的规则

  • 默认值定义

C++支持函数参数带默认值。这里所谓的默认值,指的是在调用函数时,可以不指定某些参数,编译器会自动把默认值传递到函数调用中。

  • 默认值位置

指定默认值的参数必须位于形参列表最右端,从右往左。否则会出现二义性,编译器无法处理。

  • 默认值设置

默认值可以在函数声明或函数定义中设置,只要保证不出现参数重定义即可。

2.默认参数示例

  • 在函数声明中设置默认值

这是最常见的一种情形。主要有以下两种声明方式:

  1. 声明中给参数赋默认值
  2. 声明中用类型指定默认值
float area(float radius = 5.0);

int main()
{
  float s1 = area();
  float s2 = area(6.0);

  return 0;
}
float area(float = 5.0);

int main()
{
  float s1 = area();
  float s2 = area(6.0);

  return 0;
}

以上两种方式是等价的。

  • 在函数定义中设置默认值

如果函数直接在调用前定义,此时不需要函数声明,则默认参数可以在函数定义中直接设置。

float area(float r = 5.0)
{
  return r * r *3.14;
}

int main()
{
  float s = area();

  return 0;
}

3.注意事项

  • 默认值设置位置

不管是在声明还是在定义中设置默认值,都要确保以下两点:

  1. 函数在调用时,能获取到设置的默认值
  2. 默认值不存在重复设置

若不满足以上两个条件,编译时会报错无法通过。

float area(float r)
{
  return r * r * 3.14;
}

int main()
{
  float area(float = 5.0);

  float s1 = area();
  float s2 = area(6.0);

  return 0;
}

上面的代码是可以正常运行的,原因是在函数调用之前,声明中设置了参数的默认值,即main函数中如下语句:

float area(float = 5.0);

编译器在调用函数前检测到参数默认值,能够正常完成调用。

float area(float r = 5.0);

float area(float r = 5.0)
{
  return r * r * 3.14;
}

以上代码会编译不过,原因是编译器检测到默认参数有重定义。

  • 默认值与函数重载

函数默认值不能和函数重载形成二义性,否则编译器无法判断具体使用的是那个函数。如以下代码,函数调用存在二义性,编译不通过。

float func1(float r1, float r2 = 5.0);
float func1(float r);

float func1(float r)
{
  return r * r * 3.14;
}

float func1(float r1, float r2)
{
  return r1 * r1 * 3.14;
}

int main()
{
  float s2 = func1(6.0);

  return 0;
}
  • 默认值的类型

默认值可以是常量、全局变量或者全局函数。不可以是局部变量。原因是函数参数默认值是在编译时确定的,而局部变量存在栈上,编译时不能确定。

float globalRadius = 7.0;

float gen(float magic)
{
  return magic;
}

float func1(float r)
{
  return r * r * 3.14;
}

int main()
{
  float func1(float r = globalRadius); //全局变量做默认值,OK
  float func1(float r = gen(1.0)); //全局函数做默认值,OK
  float val = 1.0;
  float func1(float r = val); //局部变量做默认值,编译不通过

  float s2 = func1();

  return 0;
}
  • 参数是引用时的默认值

若参数是引用,不能直接将实际值设为默认值。可以将全局变量作为引用参数默认值

float globalRadius = 7.0;

float func1(float &r)
{
  return r * r * 3.14;
}

int main()
{
  float func1(float &r = 1.0); //不能将常量值设为引用参数默认值,编译不过
  float func1(float &r = globalRadius); //OK

  float s2 = func1();

  return 0;
}

猜你喜欢

转载自www.cnblogs.com/jerrybai/p/10693594.html