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

被折叠的 条评论
为什么被折叠?



