默认参数值的位置是什么?只是在函数定义,或声明,或两个地方?在C++中把默认参数值放在哪里?
回答
默认参数值必须出现在声明中,因为这是调用者看到的唯一东西。
编辑:正如其他人所指出的,你可以有的定义的说法,但我会建议所有写代码,如果这是不正确的。
你可以做,但从来都没有。通常你在函数声明中做,然后所有的调用者都可以使用这个默认值。但you can do that at function definition instead然后只有那些看到定义的人才能使用默认值。
该声明通常是最“有用”的,但这取决于您想如何使用该类。
两者都无效。
最有用的地方是在声明(.h)中,以便所有用户都能看到它。
有些人喜欢在实施过添加默认值(为注释):
void foo(int x = 42,
int y = 21);
void foo(int x /* = 42 */,
int y /* = 21 */)
{
...
}
但是,这意味着重复,将增加其与代码不同步的注释的可能性(还有什么比未注释的代码更糟糕?)。
好问题... 我发现编码器通常使用声明来声明默认值。我一直在举行一个方法(或警告)或其他过基于编译器
void testFunct(int nVal1, int nVal2=500);
void testFunct(int nVal1, int nVal2)
{
using namespace std;
cout << nVal1 << << nVal2 << endl;
}
如果此功能被暴露 - 非成员,公共或受保护的 - 那么调用者应该知道他们,默认值必须位于标题中。
如果这些函数是私有的并且是非线性的,那么将默认值放在实现文件中是有意义的,因为这允许不会触发客户端重新编译的更改(对于低级库在企业规模发展中共享)。也就是说,这肯定会让人感到困惑,并且在头文件中以更直观的方式呈现API时存在文档价值,所以选择妥协 - 尽管在没有任何令人信服的理由的情况下,一致性是主要的。
虽然这是一个“老”的线程,我还是想添加以下到它:
我已经经历了下情况:
- 在类的头文件,我有
int SetI2cSlaveAddress(UCHAR addr, bool force);
- 在这个类的源文件,我有
int CI2cHal::SetI2cSlaveAddress(UCHAR addr, bool force = false) { ... }
正如人们所看到的,我已经把类源文件中的参数“力”的默认值,而不是在类的头文件。
然后我用该函数在派生类如下(派生类继承在公开的方式的基类):
SetI2cSlaveAddress(addr);
假定它会采取“力”参数为“假”“的理所当然”。
然而,编译器(放于C++ 11模式)抱怨,给了我以下编译器错误:
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp: In member function 'void CMax6956Io::Init(unsigned char, unsigned char, unsigned int)':
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: error: no matching function for call to 'CMax6956Io::SetI2cSlaveAddress(unsigned char&)'
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: note: candidate is:
In file included from /home/geertvc/mystuff/domoproject/lib/i2cdevs/../../include/i2cdevs/max6956io.h:35:0,
from /home/geertvc/mystuff/domoproject/lib/i2cdevs/max6956io.cpp:1:
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: int CI2cHal::SetI2cSlaveAddress(unsigned char, bool)
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: candidate expects 2 arguments, 1 provided
make[2]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/max6956io.cpp.o] Error 1
make[1]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/all] Error 2
make: *** [all] Error 2
但是,当我加入的默认参数在头文件的基类:
int SetI2cSlaveAddress(UCHAR addr, bool force = false);
并将其从源文件中删除基类的:
int CI2cHal::SetI2cSlaveAddress(UCHAR addr, bool force)
那么编译器很高兴,所有代码和预期一样(我可以给一个或两个参数的函数SetI2cSlaveAddress()
)!
因此,不仅对一个类的用户来说,将一个参数的默认值放在头文件中是很重要的,这同样也是编译和功能上的明智之举,显然它似乎是必须的!
您可以按照标准来做,但请记住,如果您的代码在包含默认参数的定义之前看到没有默认参数的声明,则可能出现编译错误。例如,如果包含包含没有默认参数列表的函数声明的头文件,编译器会查找该原型文件,因为它不知道默认参数值,因此原型不匹配。
如果你在定义中使用默认参数的函数,那么包含该文件,但我不会建议。
添加一个点。具有默认参数的函数声明应该是从右到左排列的和从上到下。
例如在下面的函数声明中,如果您更改声明顺序,那么编译器会给您一个缺少的默认参数错误。编译器允许您在相同范围内将函数声明与默认参数分开,但应该按照从RIGHT到LEFT(默认参数)以及从TOP到BOTTOM(函数声明默认参数的顺序)的顺序。
//declaration
void function(char const *msg, bool three, bool two, bool one = false);
void function(char const *msg, bool three = true, bool two, bool one); // Error
void function(char const *msg, bool three, bool two = true, bool one); // OK
//void function(char const *msg, bool three = true, bool two, bool one); // OK
int main() {
function("Using only one Default Argument", false, true);
function("Using Two Default Arguments", false);
function("Using Three Default Arguments");
return 0;
}
//definition
void function(char const *msg, bool three, bool two, bool one) {
std::cout<<msg<<" "<<three<<" "<<two<<" "<<one<<std::endl;
}
还有一点我还没有发现任何人提到:
如果你有虚方法,每一项声明可以有自己的默认值!
它取决于您要调用哪个值的接口。
例如在ideone
struct iface
{
virtual void test(int a = 0) { std::cout << a; }
};
struct impl : public iface
{
virtual void test(int a = 5) override { std::cout << a; }
};
int main()
{
impl d;
d.test();
iface* a = &d;
a->test();
}
它打印50
我极力劝阻你使用这样
- 1. 把认证信息放在哪里
- 2. vim:在哪里把插件变量的默认值?
- 3. 你把ivysettings.xml放在哪里?
- 4. 把CMakeLists.txt放在哪里?
- 5. 把drawRect放在哪里?
- 6. 把cellforrowatindexpath放在哪里?
- 7. 把Testdata放在哪里?
- 8. 放入参数。我应该把他们放在哪里?
- 9. 设置默认参数为在哪里条件在sql中
- 10. Python函数中的默认参数在哪里
- 11. 在哪里存储默认值asp.net
- 12. MVVM:把数据库CRUD放在哪里?
- 13. 把Firebase.setAndroidContext()函数放在哪里
- 14. 哪里把css文件放在Codeigneter中
- 15. C++默认参数值
- 16. C++默认参数值
- 17. MVC5哪里把认证表单放在web.config中?
- 18. 在C++中将默认值参数放置在变长函数中的位置?
- 19. 它可能把一个默认值函数的参数在VB.NET
- 20. 默认值:它们在哪里存储在数据库Odoo上?
- 21. C中的默认参数值
- 22. 你把dotcloud.yml文件放在哪里?
- 23. 把弹出代码放在哪里
- 24. swffit,把代码放在哪里?
- 25. 把事件监听器放在哪里?
- 26. 你把你的JavaScript放在哪里?
- 27. 把你的代表放在哪里。 。
- 28. 我该把registerDefaults放在哪里?
- 29. 把jQuery消息放在哪里?
- 30. 把gradle.properties文件放在哪里
这可能是技术上是正确的,但我不认为这是个好建议。 – 2011-02-14 06:43:51
@Marcelo Cantos:同意。 – sharptooth 2011-02-14 06:44:31
如果你想变得非常可怕,你可以实际做到这一点,但对于不同的参数。 :-) – 2011-02-14 21:03:15