Const参数的正确性
我知道关于const正确性的问题很less,在这里,声明函数及其定义不需要同意价值参数。 这是因为值参数的常量只在函数内部起作用。 这可以:
// header int func(int i); // cpp int func(const int i) { return i; }
这是否是一个最好的做法? 因为我从来没有见过任何人这样做。 我已经在其他地方看到了这个引用(不知道源代码)
“实际上,对于编译器来说,无论您是否将此const包含在值参数前面,函数签名都是相同的。”
“在函数声明中避免使用const传值参数,如果参数不被修改,仍然将参数设置为const在同一个函数的定义中。
第二段说不把const放在声明中。 我认为这是因为作为接口定义的一部分,值参数的常量是没有意义的。 这是一个实现细节。
基于这个build议,是否也推荐指针参数的指针值? (由于不能重新分配引用,因此对引用参数没有意义。)
// header int func1(int* i); int func2(int* i); // cpp int func1(int* i) { int x = 0; *i = 3; // compiles without error i = &x; // compiles without error return *i; } int func2(int* const i) { int x = 0; *i = 3; // compiles without error i = &x; // compile error return *i; }
简介:创build值参数对于捕获一些逻辑错误非常有用。 这是最佳做法吗? 你是否把const放在头文件的极端? 它是一样有用的const指针值? 为什么或者为什么不?
一些参考:
C ++ const关键字 – 使用宽松吗? 使用'const'作为函数参数
常量值参数有用的示例:
bool are_ints_equal(const int i, const int j) { if (i = j) { // without the consts this would compile without error return true; } else { return false; } // return i = j; // I know it can be shortened }
我承担:
这不是一个坏主意,但是这个问题很小,你的精力可能会更好地花在其他事情上。
在你的问题中,你提供了一个很好的例子,说明什么时候可能发生错误,但是偶尔你也会做这样的事情:
void foo(const int count ...) { int temp = count; // can't modify count, so we need a copy of it ++temp; /* ... */ }
优点和缺点都很小。
我读了很多次,在一个函数const中创build值参数是一件坏事,因为这是不必要的。
然而,我发现偶尔对我有帮助,作为一个检查,我的实现不会做我不打算的东西(如在你的问题结束时的例子)。
所以,虽然它可能不会增加调用者的价值,但它有时为我作为一个实施者增加了一点价值,而且它不会带走任何东西。 所以我觉得没有什么坏处。
例如,我可能正在实现一个C函数,它将一个指针指向一个缓冲区 – 一个指向开始的指针和一个指向结尾的指针。 我将把数据放入缓冲区,但要确保不会超出最后。 所以在函数里面有一些代码会在我添加数据的时候增加一个指针。 使指针指向缓冲区的末尾, const
参数将确保我不会编写一个意外递增结束边界指针的错误,而不是我真的应该递增的指针。
所以一个像这样的签名的fillArray函数:
size_t fillArray( data_t* pStart, data_t* const pEnd);
将防止我意外增加pStart
意外增加pStart
。 这不是一个巨大的事情,但我很确定每个在C中编程了一段时间的人都遇到过这样的错误。
不幸的是,有些编译器(我正在看你,Sun CC!)不正确地区分声明为const和不声明的参数,你可以得到关于未定义函数的错误。
我认为这取决于你的个人风格。
它不会增加或减less客户端可以传递给你的函数的东西。 本质上它就像一个编译时断言。 如果它能帮助你知道价值不会改变,那就去做吧,但我认为别人没有什么大的理由去做。
我可能不这样做的一个原因是值参数的常量是您的客户不需要知道的实现细节。 如果你后来(故意)改变你的函数,使得它实际上改变了这个值,你将需要改变函数的签名,这将迫使你的客户重新编译。
这与为什么一些人推荐没有公共虚拟方法(虚拟function是一个应该隐藏在客户端的实现细节)的原因是类似的,但我不是在这个特定的阵营。
如果有const关键字存在; 这意味着'我'(这是consttypes)的值不能被修改。 如果'i'的值在foo函数内被改变,编译器会抛出错误:“
不能修改const对象
但是改变'* i'(ie * i = 3;)意味着你没有改变'i'的值,而是'i'指向的地址值。
实际上,const函数适用于不应该被函数改变的大对象。
我们都必须不时地解开别人的C ++代码。 而且别人的C ++代码根据定义是完全混乱的:D。
所以,我经常要做的第一件事情就是将它解密(本地和全局数据stream),直到编译器投诉为止,将const
放在每个variables定义中。 这也意味着const限定值的参数,它确实有助于避免variables在函数中被修改,而我没有注意到它…
所以我非常感谢别人在任何地方都有const(包括值参数):D
我喜欢const的正确性,像这样的情况:
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}
这让我使用b
而不用担心修改它,但是我不必为复制构造函数付出代价。