Why am I getting an error converting a Foo** → Foo const**?

来源:互联网 发布:匿名飞控源码 编辑:程序博客网 时间:2024/05/13 21:57

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 aFoo* 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**.)

From:http://www.parashift.com/c++-faq/constptrptr-conversion.html


It is correct that a double ** cannot be implicitly converted to a const double **. It can be converted to a const double * const *, though.

Imagine this scenario:

const double cd = 7.0;double d = 4.0;double *pd = &d;double **ppd = &pd;const double **ppCd = ppd;  //this is illegal, but if it were possible:*ppCd = &cd;  //now *ppCd, which is also *ppd, which is pd, points to cd*pd = 3.14; // pd now points to cd and thus modifies a const value!

So, if your function does not intend to modify any of the pointers involved, change it to take a const double * const *. If it intends to do modifications, you must decide whether all the modifications it does are safe and thus const_cast can be used, or whether you really need to pass in a const double **.

From:http://stackoverflow.com/questions/19910296/how-to-convert-pointer-to-pointer-type-to-const
0 0