你用const能做到什么程度?你只是在必要的时候才把函数变成const,还是从头到尾到处都用它?例如,想象一个简单的变异子,它接受一个布尔参数:

void SetValue(const bool b) { my_val_ = b; }

这个const真的有用吗?就我个人而言,我选择广泛地使用它,包括参数,但在这种情况下,我想知道它是否值得?

我还惊讶地发现,你可以在函数声明中的形参中省略const,但可以在函数定义中包含它,例如:

. h文件

void func(int n, long l);

. cpp文件

void func(const int n, const long l)

这有什么原因吗?这对我来说有点不寻常。


当前回答

May be this wont be a valid argument. but if we increment the value of a const variable inside a function compiler will give us an error: "error: increment of read-only parameter". so that means we can use const key word as a way to prevent accidentally modifying our variables inside functions(which we are not supposed to/read-only). so if we accidentally did it at the compile time compiler will let us know that. this is specially important if you are not the only one who is working on this project.

其他回答

做一个VB。NET程序员需要使用具有50多个公开函数的c++程序,以及偶尔使用const限定符的.h文件,很难知道何时使用ByRef或ByVal访问变量。

当然,程序通过在出错的行上生成一个异常错误来告诉您,但是随后您需要猜测2-10个参数中哪一个是错误的。

所以现在我有一个令人讨厌的任务,试图说服开发人员,他们应该真正定义他们的变量(在.h文件中),以一种允许自动创建所有VB的方法。NET函数定义容易。然后他们会自鸣得意地说:“读……文档”。

我写了一个awk脚本,它解析一个.h文件,并创建所有的Declare Function命令,但没有指示哪个变量是R/O vs R/W,它只完成了一半的工作。

编辑:

在另一位用户的鼓励下,我添加了以下内容;

下面是一个(IMO)格式不佳的.h条目的例子;

typedef int (EE_STDCALL *Do_SomethingPtr)( int smfID, const char* cursor_name, const char* sql );

从我的脚本的结果VB;

    Declare Function Do_Something Lib "SomeOther.DLL" (ByRef smfID As Integer, ByVal cursor_name As String, ByVal sql As String) As Integer

注意,第一个参数中缺少“const”。如果没有它,程序(或其他开发人员)就不知道第一个参数应该传递“ByVal”。通过添加“const”,它使.h文件自文档化,以便使用其他语言的开发人员可以轻松地编写工作代码。

如果使用->*或。*操作符,这是必须的。

它会阻止你写出

void foo(Bar *p) { if (++p->*member > 0) { ... } }

我刚才差点就这么做了,但这可能不是你想要的结果。

我想说的是

void foo(Bar *p) { if (++(p->*member) > 0) { ... } }

如果我在Bar *和p之间放了一个const,编译器会告诉我。

关于编译器优化:http://www.gotw.ca/gotw/081.htm

我倾向于尽可能使用const。(或其他适合目标语言的关键字。)我这样做纯粹是因为它允许编译器做额外的优化,否则它无法做。因为我不知道这些优化可能是什么,我总是这样做,即使它看起来很傻。

据我所知,编译器很可能看到一个const值形参,然后说:“嘿,这个函数无论如何都没有修改它,所以我可以通过引用传递并节省一些时钟周期。”我不认为它会做这样的事情,因为它改变了函数的签名,但它说明了这一点。也许它会做一些不同的堆栈操作之类的…重点是,我不知道,但我知道试图比编译器更聪明只会让我感到羞耻。

c++有一些额外的包袱,有常量正确性的思想,所以它变得更加重要。

在你提到的情况下,它不会影响API的调用者,这就是为什么它不常做(并且在头文件中也没有必要)。它只影响函数的实现。

这并不是一件特别糟糕的事情,但考虑到它不会影响您的API,它的好处并不是那么大,而且它增加了类型,所以通常不这样做。