如果我这样做:
// 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
答案 0 :(得分:15)
首先,你已经承诺了编译器,但不承认你不会编辑变量的其他类用户。
在你的第二个例子中,你已经向班级的其他用户承诺,你不会编辑他们的变量,但却未能坚持这一承诺。
我还应该注意到
之间存在明显的区别bar* const variable
和
const bar* variable
和
const bar* const variable
在第一种形式中,指针永远不会改变,但您可以编辑指向的对象。在第二种形式中,您可以编辑指针(将其指向另一个对象),但不要编辑它指向的变量。在最终形式中,既不会编辑指针,也不会编辑它指向的对象。 Reference
为了对所述问题添加更多澄清,您可以始终承诺更多const而不是更少。给出一个类:
class Foo {
void func1 (int x);
void func2 (int *x);
}
您可以编译以下实现:
Foo::func1(const int x) {}
Foo::func2(const int *x) {}
或:
Foo::func1(const int x) {}
Foo::func2(const int* const x) {}
没有任何问题。您已告诉用户您可能会编辑他们的变量。在您的实现中,您告诉编译器这个特定的实现不会编辑这些变量,即使告诉用户您可能。您没有违反对用户的承诺,因此代码会编译。
答案 1 :(得分:6)
请参阅this question,this question和this question。
基本上,const只表示该函数不会修改指针的值。指针内容不是const,与标题的签名相同。
答案 2 :(得分:1)
第一个示例中的 const 关键字没有意义。你是说你不打算改变指针。但是,指针是按值传递的,所以如果你改变它就没关系;它不会影响来电者。同样,你也可以这样做:
// In header
class Foo {
void foo( int b );
};
// In cpp
void Foo::foo( const int b ) {
//Stuff
}
你甚至可以这样做:
// In header
class Foo {
void foo( const int b );
};
// In cpp
void Foo::foo( int b ) {
//Stuff
}
由于 int 是按值传递的,因此constness无关紧要。
在第二个例子中,你说你的函数接受一个指向一个类型的指针,然后将它实现为指向另一个类型的指针,因此它失败了。
答案 3 :(得分:0)
在前者中,const
不影响界面,只影响实现。您是对编译器说的,“我不打算在此函数中更改bar*
的值”。您仍然可以更改指针指向的内容。在后者中,您告诉编译器(以及所有调用者)您不会更改bar
指向的bar*
结构。
答案 4 :(得分:0)
所以第二个const在:
void Foo::foo(const bar* const);
不 是方法签名的一部分吗?
答案 5 :(得分:0)
使用指针以外的变量类型可以更容易理解。例如,您可以使用以下函数声明:
void foo( int i );
定义可能如下所示:
void foo( const int i ) { ... }
变量'i'在定义方面是否为const是一个实现细节。它对该功能的客户没有影响。
答案 6 :(得分:0)
它可能并不关心void Foo::foo(bar* const pBar)
,因为你如何处理指针本身(const或不是)与例程之外的一点并不重要。 C规则说,无论如何,对pBar的改变都不会在foo之外传播。
但是,如果它是(const bar* pBar)
,则会产生影响,因为这意味着编译器不允许调用者将指针传递给非const对象。