为什么将实参Foo** 赋给形参Foo const**时出错。

本文探讨了C++中从Foo**到Foo const**的非法转换及其潜在风险,并通过示例说明了这种转换如何可能导致意外地修改const限定的对象。文章还提供了一种常见的解决方案,即使用Foo const* const*。

原文网址:http://www.parashift.com/c++-faq-lite/constptrptr-conversion.html 感觉文章也没有说出所以然来,只是举了个例子说明潜在的危险。

c专家编程 里面解释过,但是太拗口,没有看懂。查看他的英文版也没搞不明白。


Because converting Foo**  Foo const** would be invalid and dangerous.

C++ allows the (safe) conversion Foo*  Foo const*, but gives an error if you try to implicitly convert Foo**  Foo const**.

The rationale for why that error is a good thing is given below. But first, here is the most common solution: simply change Foo const** to Foo const* const*:

class Foo { /* ... */ };

void f(Foo const** p);
void g(Foo const* const* p);

int main()
{
  Foo** p = /*...*/;
  ...
  f(p);  // ERROR: it's illegal and immoral to convert Foo** to Foo const**
  g(p);  // OK: it's legal and moral to convert Foo** to Foo const* const*
  ...
}
The reason the conversion from  Foo**    Foo const** is dangerous is that it would let you silently and accidentally modify a  const Foo object without a cast:
class Foo {
public:
  void modify();  // make some modification to the this object
};

int main()
{
  const Foo x;
  Foo* p;
  Foo const** q = &p;  // q now points to p; this is (fortunately!) an error
  *q = &x;             // p now points to x
  p->modify();         // Ouch: modifies a const Foo!!
  ...
}
If the  q = &p line were legal,  q would be pointing at  p. The next line,  *q = &x, changes  p itself (since  *q is  p) to point at  x. That would be a bad thing, since we would have lost the  const qualifier:  p is a Foo* but  x is a  const Foo. The  p->modify() line exploits  p's ability to modify its referent, which is the real problem, since we ended up modifying a  const Foo.

By way of analogy, if you hide a criminal under a lawful disguise, he can then exploit the trust given to that disguise. That's bad.

Thankfully C++ prevents you from doing this: the line q = &p is flagged by the C++ compiler as a compile-time error. Reminder: please do not pointer-cast your way around that compile-time error message. Just Say No!

(Note: there is a conceptual similarity between this and the prohibition against converting Derived** to Base**.)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值