C++ 常数问题
如果我这样做:
// In header
class Foo {
void foo(bar*);
};
// In cpp
void Foo::foo(bar* const pBar) {
//Stuff
}
编译器不会抱怨 Foo::foo 的签名不匹配。 但是,如果我有:
void foo(const bar*); //In header
void Foo::foo(bar*) {} //In cpp
代码将无法编译。
到底是怎么回事? 我正在使用 gcc 4.1.x
If I do this:
// In header
class Foo {
void foo(bar*);
};
// In cpp
void Foo::foo(bar* const pBar) {
//Stuff
}
The compiler does not complain that the signatures for Foo::foo do not match. However if I had:
void foo(const bar*); //In header
void Foo::foo(bar*) {} //In cpp
The code will fail to compile.
What is going on?
I'm using gcc 4.1.x
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用除指针之外的变量类型更容易理解。 例如,您可以有以下函数声明:
定义可以如下所示:
变量“i”在定义端是否为 const 是一个实现细节。 它对该功能的客户端没有影响。
This is simpler to understand with a variable type other than a pointer. For example, you can have the following function declaration:
The definition can look like this:
Whether the variable 'i' is const or not on the definition side is an implementation detail. It has no impact for the clients of that function.
它可能不太关心
void Foo::foo(bar* const pBar)
因为你如何对待指针本身(const 与否)在例程之外一点也不重要。 C 规则规定,无论怎样,对 pBar 的更改都不会传播到 foo 之外。但是,如果它是
(const bar* pBar)
,那就有区别了,因为这意味着编译器不允许调用者传入指向非 const 对象的指针。It probably doesn't care much about
void Foo::foo(bar* const pBar)
because how you treat the pointer itself (const or not) doesn't matter one bit outside of the routine. The C rules say that no change to pBar will travel outside of foo either way.However, if it is
(const bar* pBar)
, that makes a difference, because it means the compiler is not to allow callers to pass in pointers to non-const objects.在前者中,
const
不影响接口,只影响实现。 您对编译器说:“我不会更改此函数中bar*
的值”。 您仍然可以更改指针所指向的内容。 在后者中,您告诉编译器(和所有调用者)您不会更改bar*
指向的bar
结构。In the former, the
const
doesn't affect the interface, only the implementation. You are saying to the compiler, "I am not going to change the value of thebar*
within this function". You can still change what is pointed to by the pointer. In the latter, you are telling the compiler (and all callers) that you will not change thebar
structure that thebar*
points to.首先,您向编译器(但不是该类的其他用户)承诺您不会编辑该变量。
在第二个示例中,您已向该类的其他用户承诺您不会编辑他们的变量,但未能遵守该承诺。
之间有明显的区别。
我还应该注意到, and 和
and
在第一种形式中,指针永远不会改变,但您可以编辑所指向的对象。 在第二种形式中,您可以编辑指针(将其指向另一个对象),但不能编辑它指向的变量。 在最终形式中,您既不会编辑指针,也不会编辑它指向的对象。 参考
添加更多内容对所述问题的澄清,你总是可以承诺更多 const 而不是更少。 给定一个类:
您可以编译以下实现:
或:
没有任何问题。 您已经告诉您的用户您可以编辑他们的变量。 在您的实现中,您已经告诉编译器此特定实现不会编辑这些变量,即使告诉用户您可以编辑这些变量。 您没有违背对用户的承诺,因此代码可以编译。
In the first, you've promised the compiler, but not other users of the class that you will not edit the variable.
In your second example, you've promised other users of the class that you will not edit their variable, but failed to uphold that promise.
I should also note that there is a distinct difference between
and
and
In the first form, the pointer will never change, but you can edit the object that is pointed to. In the second form, you can edit the pointer(point it to another object), but never the variable that it points to. In the final form, you will neither edit the pointer, nor the object it points to. Reference
To add a bit more of a clarification to the question stated, you can always promise MORE const than less. Given a class:
You can compile the following implementation:
or:
without any problems. You've told your users that you may possibly edit their variables. In your implementation, you've told the compiler that this particular implementation will not edit those variables, even though the told the users you might. You haven't broken a promise to the user, and so the code compiles.
请参阅此问题,这个问题,以及这个问题。
基本上,const 仅意味着该函数不会修改指针的值。 指针内容不是 const,与标头的签名相同。
See this question, this question, and this question.
Basically, the const only means that the function will not modify the pointer's value. The pointers contents are not const, the same as the header's signature.
第一个示例中的 const 关键字没有意义。 您是说您不打算更改指针。 但是,指针是按值传递的,因此更改与否并不重要; 它不会影响调用者。 同样,您也可以这样做:
您甚至可以这样做:
由于 int 是按值传递的,因此常量并不重要。
在第二个示例中,您说您的函数采用指向一种类型的指针,但随后将其实现为采用指向另一种类型的指针,因此它失败。
The const keyword in the first example is meaningless. You are saying that you don't plan on changing the pointer. However, the pointer was passed by value and so it dos not matter if you change it or not; it will not effect the caller. Similarly, you could also do this:
You can even do this:
Since the int is passed by value, the constness does not matter.
In the second example you are saying that your function takes a pointer to one type, but then implement it as taking a pointer to another type, therefore it fails.
所以第二个常量:
不是是方法签名的一部分吗?
So the second const in:
Is not part of the method signature?