sud*_*008 36 c++ oop header-files
编译器: g ++ 4.7.2
好.所以我对.h和.cpp文件中的默认参数感到困惑.许多地方(包括本网站)都提到默认参数只能添加到.h文件而不能添加到.cpp文件中.但是,这段代码证明错了:
test1.h
#pragma once
#include <iostream>
using namespace std;
class Class{
public:
Class(int, int, int=1);
};
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
现在,根据我测试的内容,可以将默认参数添加到.cpp文件中.但是,以下限制包含:
存在于.cpp和.h文件中的默认参数不应重叠.即Class(a, b, c=1)(在.h文件中)和
Class::Class(a,b,c=2)(在.cpp文件中)无效.
众所周知,一旦添加了默认参数,之后声明的所有变量也必须包含默认值.让我们称之为defpara规则.现在,
函数声明(.h文件)中声明的变量应遵守defpara规则,即Class(a, b=2, c)(在.h文件中)无效,无论.cpp文件中声明的是什么.
如果考虑具有默认值的变量(作为.h和.cpp文件中的默认值的交集),它将遵循defpara规则.即Class(a, b, c=1)(在.h文件中)和
Class::Class(a,b=2,c)(在.cpp文件中)有效.但是Class(a, b,
c=1)(在.h文件中)和Class::Class(a=2,b,c)(在.cpp文件中)无效.
所以....我是对的,错的???
Mat*_*son 68
如果函数在头文件中声明,则默认值应始终放在头文件中.
这是因为编译器将使用头文件用于所有使用您的类的编译单元[除非您是"顽皮"并且不要在任何地方使用头文件].
由于编译器在编译CALLS函数的代码(在本例中为构造函数)时添加了默认参数,因此.cpp文件中的默认值无关紧要.
当然,在这种情况下,只有一个头文件的"用户",并且只有一个调用构造函数的位置.但是.cpp文件中的默认值通常是错误的[除非它是本地函数].
如果你"混合"默认值,你会得到非常"有趣"的错误 - 例如,如果你的.cpp有一个默认值,而headefile是另一个默认值.如果你真的很熟练,你甚至可以让编译器为函数的不同调用生成不同的默认值,如果代码依赖于默认值是某个特定值,这几乎肯定会导致一些头痛.并且不要试图将标题中的默认值复制到.cpp文件"只是为了让它更容易看到".如果有人更改了默认值,那么几乎可以肯定要么两个地方都不会改变,可能更糟糕的是:更改错误的默认值,因此它不会按预期执行.
Dav*_*own 24
这只能起作用,因为你的main函数也在你的test.cpp文件中,因此它会看到你的类实现中指定的默认参数.如果将main函数放在仅包含的单独文件中test.h,则此代码将无法编译.
查看它的另一种方式是,当其他一些包含时test.h,所有代码看到的都是声明的内容test.h,因此不会使用放在别处的默认参数.
.h vs. .cpp是一只红鲱鱼.规则是默认参数可以在函数声明和函数定义中使用.您不能重新定义默认参数,甚至不能重新定义相同的值.所以这不合法:
void f(int, int = 3);
void f(int, int = 3); // error: redefinition of default argument
Run Code Online (Sandbox Code Playgroud)
但是,后续声明可以添加默认参数:
void f(int, int = 3);
void f(int = 4, int = 3);
f(); // calls f(4, 3);
Run Code Online (Sandbox Code Playgroud)
此外,在调用函数的任何位置,都可以使用在该点看到的默认参数:
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);
Run Code Online (Sandbox Code Playgroud)
在原始示例中,.h文件定义了一个默认参数,并且使用该标头的任何转换单元都可以使用该默认参数:
Class c3(1, 2, 3);
Class c2(1, 2);
Run Code Online (Sandbox Code Playgroud)
此外,.cpp文件定义了一个额外的默认参数,因此在该声明之后,可以使用一个,两个或三个参数调用构造函数:
Class c3(1, 2, 3);
class c2(1, 2);
class c1(1);
Run Code Online (Sandbox Code Playgroud)