为什么必须将实参强制转换为const ?

Why must an argument ever be cast to const?

本文关键字:转换 const 实参 为什么      更新时间:2023-10-16

我的理解是,参数声明中的const表示被声明的函数不会改变const值。那么,为什么这会对调用者传递的参数的一致性提出要求呢?

定义代码:
void Func(const Foo**);
main()
{
  Foo* fooPtr;
  Func(&fooPtr);
}

Visual Studio 2012编译器输出:

> error C2664: 'Func' : cannot convert parameter 1 from 'Foo**' to 'const Foo**'
> Conversion loses qualifiers

但是下面的工作:

main()
{
  Foo* fooPtr;
  Func(const_cast<const Foo**>(&fooPtr));
}

背后的理论是什么?

如果允许转换,则可以使用它来规避const正确性:

const Foo const_foo;
void evil(const Foo** p) {
    *p = &const_foo; // *p is 'const Foo*', so this assignment is allowed
}
int main() {
    Foo* p;
    evil(&p);     // modifies p to point to const_foo
    p->modify();  // BOOM! Modifying a constant object
}

可以转换为const Foo* const*;它不允许您将Foo*更改为指向其他任何东西,因此不能破坏常量正确性。这比使用一个不可靠的石膏,然后抱着最好的希望要好;虽然你应该问问自己,如果你不想改变它,为什么不简单地按值传递指针

当Func(&fooPtr)确实修改了fooPtr而保持*fooPtr不变时,应该有两个版本的Func(),一个是根据另一个定义的:

void Func(const Foo**);
void Func(Foo** fooHndl)
{
  Func(const_cast<const Foo**>(fooHndl));
}

这允许用句柄(**)调用Func()来调用const对象或非const对象