我最近与另一位C++开发人员就以下用途进行了交流const:
void Foo(const int bar);
Run Code Online (Sandbox Code Playgroud)
他认为const以这种方式使用是很好的做法.
我认为它对函数的调用者没有任何作用(因为参数的副本将被传递,因此对于覆盖没有额外的安全保证).此外,这样做可以防止实现者Foo修改其参数的私有副本.因此,它既要求又要宣传实施细节.
不是世界末日,但肯定不是值得推荐的良好做法.
我很好奇别人对这个问题的看法.
好吧,我没有意识到参数的常数没有考虑到函数的签名.因此,可以const在实现(.cpp)中标记参数,而不是在标题(.h)中标记- 并且编译器就可以了.既然如此,我想政策应该与制作局部变量const相同.
人们可以提出这样的论点:在标题和源文件中具有不同的看起来签名会使其他人感到困惑(因为它会使我感到困惑).虽然我试着用我写的任何内容来遵循最小惊讶原则,但我认为期望开发人员认为这是合法且有用的是合理的.
我正在考虑在我的C++代码中更多地使用pure/const函数.(GCC中的pure/const属性)
但是,我很好奇我应该对它有多严格,哪些可能会破坏.
最明显的情况是调试输出(无论采用何种形式,都可以在cout,某些文件或某些自定义调试类中).我可能会有很多功能,尽管有这种调试输出,但它们没有任何副作用.无论是否进行调试输出,这绝对不会影响我的应用程序的其余部分.
或者我想到的另一种情况是使用一些SmartPointer类,它可能在调试模式下在全局内存中做一些额外的事情.如果我在pure/const函数中使用这样的对象,它确实会有一些轻微的副作用(在某种意义上说某些内存可能会有所不同),但它们不应该有任何真正的副作用(从某种意义上说,行为是在任何方式不同).
类似于互斥和其他东西.我可以想到许多复杂的情况,它有一些副作用(从某种意义上说,某些内存会有所不同,甚至可能会创建一些线程,进行某些文件系统操作等),但没有计算差异(所有这些副作用)很可能被遗漏,我甚至更愿意).
因此,总而言之,我想将函数标记为纯/ const,严格意义上不是纯/ const.一个简单的例子:
int foo(int) __attribute__((const));
int bar(int x) {
int sum = 0;
for(int i = 0; i < 100; ++i)
sum += foo(x);
return sum;
}
int foo_callcounter = 0;
int main() {
cout << "bar 42 = " << bar(42) << endl;
cout << "foo callcounter = " << foo_callcounter << endl;
}
int foo(int x) {
cout << "DEBUG: foo(" << x << ")" << endl;
foo_callcounter++;
return x; …Run Code Online (Sandbox Code Playgroud) 允许这样做的背后的设计理由是什么?
const Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
但不是这个
Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
?
第二行可能出现什么问题(第一行不会出错)?
如果我有这个代码:
void Foo(aBasicType aIn) //Where aBasicType is int, char etc.
{
//...
}
Run Code Online (Sandbox Code Playgroud)
制作它是否有任何意义,const aBasicType因为它无论如何都会被复制?我问的原因之一是因为我在第三方代码中看到了它,并且想知道是否有一些我不知道的东西.
我的类中有一个const方法,不能改为非const.在这个方法中,我需要调用一个非const方法,但编译器不允许我这样做.
它有什么办法吗?以下是我的代码的简化示例:
int SomeClass::someMethod() const {
QColor saveColor = color();
setColor(QColor(255,255,255)); // Calling non-const method
// ....
setColor(saveColor); // restore color
return 1;
}
Run Code Online (Sandbox Code Playgroud) 以下代码抛出错误消息,我无法弄清楚问题是什么 - 是这个词static,还是const?我究竟做错了什么?
#include <iostream>
using namespace std;
class SampleClass
{
private:
int value;
static int counter;
public:
SampleClass(int i)
{
value = i;
counter++;
}
static int countSomeClass() const
{
return counter;
}
void showValue()
{
cout << value << endl;
}
};
int main()
{
SampleClass test(50);
test.showValue();
test.countSomeClass();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
main.cpp:16:35:错误:静态成员函数static int SampleClass :: countSomeClass()不能有cv-qualifier
static int countSomeClass()const
我一直在寻找有关如何做某事的例子,并看到了这两个变种:
std::string const &s;
const std::string &s;
Run Code Online (Sandbox Code Playgroud)
在不同的片段.
thx你的答案:)
是否有任何情况下const&&在range-for循环中使用它是否有意义?
for (const auto && x : c) // ?
Run Code Online (Sandbox Code Playgroud) 以下代码无法在Ideone上实时编译:
#include <iostream>
using namespace std;
int main() {
const double kPi = 3.14;
constexpr double kPi2 = 2.0*kPi;
cout << kPi2;
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
Run Code Online (Sandbox Code Playgroud)prog.cpp: In function 'int main()': prog.cpp:6:30: error: the value of 'kPi' is not usable in a constant expression constexpr double kPi2 = 2.0*kPi; ^ prog.cpp:5:15: note: 'kPi' was not declared 'constexpr' const double kPi = 3.14;
将const声明替换为kPiwith constexpr,它会成功编译.
在另一方面,如果int是用来代替double,好像const 还有戏剧与constexpr …
我想有一个常量材料的目录,所以我可以使用如下所示的代码:
Dim MyDensity, MySymbol
MyDensity = ALUMINUM.Density
MySymbol = ALUMINUM.Symbol
Run Code Online (Sandbox Code Playgroud)
显然铝的密度和符号预计不会改变所以我希望它们是常数但我喜欢简单的点符号.
我看到了几个选项,但我不喜欢它们.
为每种材料的每个属性制作常量.这似乎太多常数,因为我可能有20个材料,每个都有5个属性.
Const ALUMINUM_DENSITY As Float = 169.34
Const ALUMINUM_SYMBOL As String = "AL"
Run Code Online (Sandbox Code Playgroud)使用所有材质定义枚举并生成返回属性的函数.密度不是很明显,因为它的值是由函数返回的.
Public Enum Material
MAT_ALUMINUM
MAT_COPPER
End Enum
Public Function GetDensity(Mat As Material)
Select Case Mat
Case MAT_ALUMINUM
GetDensity = 164.34
End Select
End Function
Run Code Online (Sandbox Code Playgroud)似乎Const Structs或Const Objects不会解决这个问题,但也许我错了(甚至可能不被允许).有没有更好的办法?