[英]Setting Default Parameters in C++
我对C ++中函数参数的默认值有一个疑问。 我遇到的问题可能是由于我对在函数原型或函数标头或两者中应该在何处声明/定义参数缺乏了解。 代码如下,并指出了错误:
#include <iostream>
using namespace std;
float volume(float l, float w, float h);
int main() {
float length;
float width;
float height;
cout << volume() << endl; // Here, with 'volume()' underlined, it says:
//no matching function for call to 'volume()'
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){
float vol = l * w * h;
return vol;
}
在另一尝试中,发生了以下情况:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){ //Here, Xcode says that
// that the error is: Redefinition of default argument. < which I believe I understand.
float vol = l * w * h;
return vol;
}
在我的最后一次尝试中,我这样做是:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l, float w, float h){
float vol = l * w * h;
return vol;
}
有人可以向我解释为什么后者起作用而前两个却不起作用的逻辑吗? 代码是否还有其他方法可以与在其他地方指定的参数或在其他位置设置的默认值相同的方式工作? 在这方面是否有任何约定或更偏爱的做法?
亚当
C ++和C是自上而下解析的。 当编译器解释一条语句时,它不知道尚未读取的内容。
在第一个示例中,您声明一个名为“ volume”的函数,原型为采用3个浮点数并返回一个浮点数。 然后,您尝试调用一个不包含任何参数的名为“ volume”的函数,该函数尚不存在(这将是一个不同的函数,因为C ++支持多态性)。 稍后您定义一个函数,该函数可以采用0、1、2或3个浮点数,但它都为时已晚,并且与第一个原型不兼容。
您的第二个示例从直觉上讲是错的,有点像两次定义变量,但是对于默认值相同时为什么它是无效代码,我没有任何具体信息。
必须在函数原型中指定默认参数,这些默认参数必须在首次使用之前出现,以便编译器知道它。 通常,您会将带有默认值的原型放在代码上方的头文件中。
处理共享头文件中的默认参数时要特别注意的一件事,尤其是在将其与动态库一起使用时:参数的默认值存储在调用方中,而不存储在被调用的函数中。 也就是说,如果您使用新的默认值更新该函数并且不重建调用该函数的代码,则调用代码仍将使用旧的默认值。
除了以上来自Bjarne Stroustrup的答案
默认参数在函数声明时进行类型检查,并在调用时进行评估。 默认参数只能提供给尾随参数。 例如:
int f(int,int = 0,char * = 0); // 好
int g(int = 0,int = 0,char *); //错误
int h(int = 0,int,char * = 0); //错误
可以在同一范围内的后续声明中重复使用默认参数,但不能更改。 例如:
无效f(int x = 7);
无效f(int = 7); // 好
无效f(int = 8); //错误:不同的默认参数
无效g(){无效f(int x = 9); //好:此声明隐藏了外部声明}
在嵌套作用域中声明名称,以便在外部作用域中隐藏相同名称的声明是容易出错的。
可以在函数声明中定义默认值,就像您在第三次尝试中所做的那样。 这意味着它们通常出现在头文件中,尽管这不是规则。
请注意,函数声明是作用域的。 这意味着一个函数可以有多个声明,只要它们具有不同的作用域即可:
void f(int);
int main() {
f(3); // argument should specified.
void f(int = 1);
f(); // calls f(1)
}
void f(int n = 2) {
}
void g() {
f(); // calls f(2)
}
第二次尝试将默认值放在函数的声明和定义上。 这会导致编译器感到困惑,因为它们属于同一范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.