COMPILER: g++ 4.7.2
编译器:g++ 4.7.2
Ok. So I am confused about default parameters in .h
and .cpp
files. It is mentioned in many places( including this site) that default parameters can be added only in .h files and not in .cpp files. However, this code proves it wrong:
好的。所以我混淆了。h和。cpp文件中的默认参数。很多地方(包括本网站)都提到,默认参数只能添加在.h文件中,而不是在.cpp文件中。然而,这段代码证明了它的错误:
test1.h
test1.h
#pragma once
#include <iostream>
using namespace std;
class Class{
public:
Class(int, int, int=1);
};
test1.cpp
test1.cpp
#include "test1.h"
Class::Class(int a, int b=2, int c)
{
cout<<a<<" "<<b<<" "<<c<<endl;
}
int main()
{
Class a(1);
return 0;
}
Now, according to what I have tested, default parameters can be added to .cpp
files. However, the following restrictions hold:
现在,根据我所测试的,默认参数可以添加到.cpp文件中。但是,以下的限制是:
-
The default parameters present in
.cpp
and.h
file should not overlap. i.e.Class(a, b, c=1)
(in .h file) andClass::Class(a,b,c=2)
( in .cpp file) is invalid.在.cpp和.h文件中出现的默认参数不应该重叠。Class(a,b,c= 1) (in .h file)和Class::Class(a,b,c=2)(in .cpp文件)是无效的。
It is a well known rule that once default parameters have been added, all the variables declared after that must also contain default values. Lets call this the defpara rule. Now,
这是一个众所周知的规则,一旦添加了默认参数,所有声明之后的变量都必须包含默认值。让我们称之为defpara规则。现在,
-
The variables stated in the function declaration(
.h
file) should obey the defpara rule i.e.Class(a, b=2, c)
(in .h file) is invalid irrespective of what's declared in .cpp file.函数声明(.h文件)中声明的变量应该遵守defpara规则,即Class(a, b=2, c)(在.h文件中)是无效的,不管在.cpp文件中声明了什么。
-
If one considers the variables having default values (as an intersection of default values in
.h
and.cpp
files), it would follow the defpara rule. i.e.Class(a, b, c=1)
(in .h file) andClass::Class(a,b=2,c)
( in.cpp
file) is valid. ButClass(a, b, c=1)
(in .h file) andClass::Class(a=2,b,c)
( in.cpp
file) is invalid.如果考虑具有默认值的变量(在.h和.cpp文件中作为默认值的交集),它将遵循defpara规则。Class(a,b,c =1) (in .h file)和Class::Class(a,b=2,c)(in .cpp文件)是有效的。但是类(a, b,c =1)(在.h文件中)和类::Class(a=2,b,c)(在.cpp文件中)是无效的。
So....I am right, wrong???
所以....我是对的,错了吗? ? ?
4 个解决方案
#1
15
This only works because your main function is also in your test.cpp
file, so it sees the default argument specified in your class' implementation. If you put your main
function in a separate file that only includes test.h
, this code will not compile.
这只能起作用,因为您的主要功能也在您的测试中。cpp文件,因此它看到了在类的实现中指定的默认参数。如果将主函数放在单独的文件中,只包含测试。这个代码不会编译。
Another way of looking at it is, when some other includes test.h
, all that code sees is what is declared in test.h
, so default arguments put elsewhere will not be used.
另一种看待它的方法是,当一些其他的包括测试。所有代码看到的都是测试中声明的内容。因此,其他地方的默认参数将不会被使用。
#2
35
Defaults should always go in the header file, if the function is declared in a header file.
如果函数是在头文件中声明的,那么默认值应该总是在头文件中。
This is because the compiler will use the header file for ALL compile units that use your class [unless you are being "naughty" and don't use the header file everywhere it should go].
这是因为编译器将为所有使用您的类的编译单元使用头文件(除非您是“淘气”,并且不要在任何地方使用头文件)。
Since the compiler adds default arguments when it compiles the code that CALLS the function (in this case the constructor), it won't matter what the defaults are in the .cpp file.
由于编译器在编译调用函数的代码时添加了默认参数(在本例中是构造函数),所以在.cpp文件中默认值是什么都不重要。
Of course, in this case, there are only one "user" of the headerfile, and only one place where the constructor is called. But having defaults in the .cpp file is generally wrong [unless it's a local function].
当然,在这种情况下,只有一个“用户”的headerfile,并且只有一个地方的构造函数被调用。但是,在.cpp文件中出现默认值通常是错误的(除非它是一个局部函数)。
You get very "interesting" bugs if you "mix" defaults - e.g. if your .cpp has one default, and the headefile a different one. If you are really skilled, you can even get the compiler to generate different defaults for different calls to the function, which will almost certainly lead to some headscratching if the code relies on the default being some particular value. And don't be tempted to copy the defaults from the header to the .cpp file "just to make it easier to see". If someone ever changes the default, then it's almost certainly either not going to change in both places, and possibly worse: change the wrong defaults, so it doesn't do what was intended.
如果你“混合”默认值,你会得到非常“有趣”的错误——例如,如果你的.cpp有一个默认值,而headefile则是另一个默认值。如果你真的很熟练,你甚至可以让编译器为函数的不同调用生成不同的默认值,如果代码依赖于某个特定值,这几乎肯定会导致一些头痛。不要试图将默认值从header复制到.cpp文件,“只是为了让它更容易看到”。如果有人更改了默认值,那么几乎可以肯定,这两种情况都不会发生变化,而且可能更糟:更改错误的默认值,所以它不会执行原本打算做的事情。
#3
5
.h vs. .cpp is a red herring. The rule is that default arguments can be used in function declarations and in the function's definition. You are not allowed to redefine a default argument, not even to the same value. So this is not legal:
.h vs. cpp是一个红鲱鱼。规则是,默认参数可以用于函数声明和函数的定义。您不允许重新定义默认参数,甚至不允许重新定义相同的值。所以这是不合法的:
void f(int, int = 3);
void f(int, int = 3); // error: redefinition of default argument
However, subsequent declarations can add default arguments:
但是,随后的声明可以添加默认参数:
void f(int, int = 3);
void f(int = 4, int = 3);
f(); // calls f(4, 3);
Further, at any point where the function is called, the default arguments that have been seen at that point can be used:
此外,在调用该函数的任何地方,可以使用在该点上看到的默认参数:
void f(int, int =3);
f(1); // calls f(1, 3);
void f(int = 4, int = 3);
f(1); // calls f(1, 3);
f(); // calls f(4, 3);
In the original example, the .h file defines one default argument, and any translation unit that uses that header can use that default argument:
在原始示例中,.h文件定义了一个默认参数,任何使用该头的翻译单元都可以使用这个默认参数:
Class c3(1, 2, 3);
Class c2(1, 2);
Further, the .cpp file defines an additional default argument, so after that declaration the constructor can be called with one, two, or three arguments:
此外,.cpp文件定义了一个附加的默认参数,因此在声明之后,构造函数可以用一个、两个或三个参数来调用:
Class c3(1, 2, 3);
class c2(1, 2);
class c1(1);
#4
2
There is no such thing as a default parameter for the definition of a file in C++ - it only exists in the declaration.
在c++中,对于文件的定义没有默认参数——它只存在于声明中。
What happens is the compiler sees a function that is missing the latter parameters. If those are default it can fill in the blanks to construct the object code to call the function as if the function call had those parameters.
所发生的是编译器看到一个函数,它忽略了后一个参数。如果这些是默认值,它可以填充空格来构造对象代码来调用函数,就好像函数调用具有这些参数一样。
PS: Item 38/Scott Myers/Effective C++ - Never redefine an inherited default parameter value.
项目38/Scott Myers/有效c++ -永远不要重新定义继承的默认参数值。
#1
15
This only works because your main function is also in your test.cpp
file, so it sees the default argument specified in your class' implementation. If you put your main
function in a separate file that only includes test.h
, this code will not compile.
这只能起作用,因为您的主要功能也在您的测试中。cpp文件,因此它看到了在类的实现中指定的默认参数。如果将主函数放在单独的文件中,只包含测试。这个代码不会编译。
Another way of looking at it is, when some other includes test.h
, all that code sees is what is declared in test.h
, so default arguments put elsewhere will not be used.
另一种看待它的方法是,当一些其他的包括测试。所有代码看到的都是测试中声明的内容。因此,其他地方的默认参数将不会被使用。
#2
35
Defaults should always go in the header file, if the function is declared in a header file.
如果函数是在头文件中声明的,那么默认值应该总是在头文件中。
This is because the compiler will use the header file for ALL compile units that use your class [unless you are being "naughty" and don't use the header file everywhere it should go].
这是因为编译器将为所有使用您的类的编译单元使用头文件(除非您是“淘气”,并且不要在任何地方使用头文件)。
Since the compiler adds default arguments when it compiles the code that CALLS the function (in this case the constructor), it won't matter what the defaults are in the .cpp file.
由于编译器在编译调用函数的代码时添加了默认参数(在本例中是构造函数),所以在.cpp文件中默认值是什么都不重要。
Of course, in this case, there are only one "user" of the headerfile, and only one place where the constructor is called. But having defaults in the .cpp file is generally wrong [unless it's a local function].
当然,在这种情况下,只有一个“用户”的headerfile,并且只有一个地方的构造函数被调用。但是,在.cpp文件中出现默认值通常是错误的(除非它是一个局部函数)。
You get very "interesting" bugs if you "mix" defaults - e.g. if your .cpp has one default, and the headefile a different one. If you are really skilled, you can even get the compiler to generate different defaults for different calls to the function, which will almost certainly lead to some headscratching if the code relies on the default being some particular value. And don't be tempted to copy the defaults from the header to the .cpp file "just to make it easier to see". If someone ever changes the default, then it's almost certainly either not going to change in both places, and possibly worse: change the wrong defaults, so it doesn't do what was intended.
如果你“混合”默认值,你会得到非常“有趣”的错误——例如,如果你的.cpp有一个默认值,而headefile则是另一个默认值。如果你真的很熟练,你甚至可以让编译器为函数的不同调用生成不同的默认值,如果代码依赖于某个特定值,这几乎肯定会导致一些头痛。不要试图将默认值从header复制到.cpp文件,“只是为了让它更容易看到”。如果有人更改了默认值,那么几乎可以肯定,这两种情况都不会发生变化,而且可能更糟:更改错误的默认值,所以它不会执行原本打算做的事情。
#3
5
.h vs. .cpp is a red herring. The rule is that default arguments can be used in function declarations and in the function's definition. You are not allowed to redefine a default argument, not even to the same value. So this is not legal:
.h vs. cpp是一个红鲱鱼。规则是,默认参数可以用于函数声明和函数的定义。您不允许重新定义默认参数,甚至不允许重新定义相同的值。所以这是不合法的:
void f(int, int = 3);
void f(int, int = 3); // error: redefinition of default argument
However, subsequent declarations can add default arguments:
但是,随后的声明可以添加默认参数:
void f(int, int = 3);
void f(int = 4, int = 3);
f(); // calls f(4, 3);
Further, at any point where the function is called, the default arguments that have been seen at that point can be used:
此外,在调用该函数的任何地方,可以使用在该点上看到的默认参数:
void f(int, int =3);
f(1); // calls f(1, 3);
void f(int = 4, int = 3);
f(1); // calls f(1, 3);
f(); // calls f(4, 3);
In the original example, the .h file defines one default argument, and any translation unit that uses that header can use that default argument:
在原始示例中,.h文件定义了一个默认参数,任何使用该头的翻译单元都可以使用这个默认参数:
Class c3(1, 2, 3);
Class c2(1, 2);
Further, the .cpp file defines an additional default argument, so after that declaration the constructor can be called with one, two, or three arguments:
此外,.cpp文件定义了一个附加的默认参数,因此在声明之后,构造函数可以用一个、两个或三个参数来调用:
Class c3(1, 2, 3);
class c2(1, 2);
class c1(1);
#4
2
There is no such thing as a default parameter for the definition of a file in C++ - it only exists in the declaration.
在c++中,对于文件的定义没有默认参数——它只存在于声明中。
What happens is the compiler sees a function that is missing the latter parameters. If those are default it can fill in the blanks to construct the object code to call the function as if the function call had those parameters.
所发生的是编译器看到一个函数,它忽略了后一个参数。如果这些是默认值,它可以填充空格来构造对象代码来调用函数,就好像函数调用具有这些参数一样。
PS: Item 38/Scott Myers/Effective C++ - Never redefine an inherited default parameter value.
项目38/Scott Myers/有效c++ -永远不要重新定义继承的默认参数值。