c++ - 从 int** 到 const int** 的转换

标签 c++ pointers

为什么我会进入这段代码:

void foo ( const int ** );

int main() {
    int ** v = new int * [10];
    foo(v);

    return 0;
}

这个错误:

invalid conversion from ‘int**’ to ‘const int**’ [-fpermissive]|

我认为可以将非常量转换为常量。

最佳答案

这是因为您正试图将 int** 转换为 const int**

int ** v = new int * [10]; // v is int**
foo(v); //but foo takes const int**
  • int ** 是:“指向整数指针的指针”。
  • const int ** 是:“指向常量整数的指针”。

const 的使用是一个契约,您不能通过间接引用两个引用来满足这个契约。

来自标准:

const char c = 'c';
char* pc;
const char** pcc = &pc;   // not allowed (thankfully!)
                ^^^ here the bundit is hidden under const: "I will not modify"
*pcc = &c;                // *pcc is "pointer to const" right? so this is allowed...
*pc = 'C';                // would allow to modify a const object, *pc is char right?

因此可以修改 const char always,只需使用上面的过程

还有:

char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char * const*ps = a; // no error!

引用自以下链接:

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.

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

与此相关的还有无效转换Derived** → Base**。如果转换 Derived** → Base** 是合法的,则可以取消引用 Base**(生成 Base*),并且Base* 可以指向不同派生类的对象,这可能会导致严重的问题。看看为什么:

class Vehicle {
public:
  virtual ~Vehicle() { }
  virtual void startEngine() = 0;
};

class Car : public Vehicle {
public:
  virtual void startEngine();
  virtual void openGasCap();
};

class NuclearSubmarine : public Vehicle {
public:
  virtual void startEngine();
  virtual void fireNuclearMissle();
};

int main()
{
  Car   car;
  Car*  carPtr = &car;
  Car** carPtrPtr = &carPtr;
  Vehicle** vehiclePtrPtr = carPtrPtr;  // This is an error in C++
  NuclearSubmarine  sub;
  NuclearSubmarine* subPtr = ⊂
  *vehiclePtrPtr = subPtr;
  // This last line would have caused carPtr to point to sub !
  carPtr->openGasCap();  // This might call fireNuclearMissle()!
  ...
}

http://www.parashift.com/c++-faq-lite/derivedptrptr-to-baseptrptr.html

考虑:

class Vehicle {
public:
  virtual ~Vehicle() { }
  virtual void startEngine() = 0;
};
class Car : public Vehicle {
public:
  virtual void startEngine(){printf("Car engine brummm\n");}
  virtual void openGasCap(){printf("Car: open gas cap\n");}
    virtual void openGasCap2(){printf("Car: open gas cap2\n");}
      virtual void openGasCap3(){printf("Car: open gas cap3\n");}
            virtual void openGasCap4(){printf("Car: open gas cap4\n");}
}; 
class NuclearSubmarine : public Vehicle {
public:
    int i;
  virtual void startEngine(){printf("Nuclear submarine engine brummm\n");}
    virtual void fireNuclearMissle3(){printf("Nuclear submarine: fire the missle3!\n");}
    virtual void fireNuclearMissle(){printf("Nuclear submarine: fire the missle!\n");}
  virtual void fireNuclearMissle2(){printf("Nuclear submarine: fire the missle2!\n");}
};   
int main(){
  Car   car; Car*  carPtr = &car;
  Car** carPtrPtr = &carPtr;
  //Vehicle** vehiclePtrPtr = carPtrPtr;  // This is an error in C++, But:
  Vehicle** vehiclePtrPtr = reinterpret_cast<Vehicle**>(carPtrPtr);
  NuclearSubmarine  sub; NuclearSubmarine* subPtr = &sub;
  *vehiclePtrPtr = subPtr; // carPtr points to sub !
  carPtr->openGasCap();  // Nuclear submarine: fire the missle3!
  carPtr->openGasCap2();  // Nuclear submarine: fire the missle!
  carPtr->openGasCap3();  // Nuclear submarine: fire the missle2!
  //carPtr->openGasCap4();  // SEG FAULT 
}

关于c++ - 从 int** 到 const int** 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16390294/

相关文章:

c - 为什么我不能将二维数组的名称分配给二维指针?

c++ - 右值引用和类设计

使用函数更改指针包含的地址

c++ - 我怎样才能安全地将 float *x 变成 const float *const *y?

c++ - 指针表达式 : *ptr++, *++ptr 和++*ptr

c++ - C2664 无法从 'initializer list' 转换参数

c++ - Openmp线程休眠

c++ - 如何在QT上暂停和重启Qtimer

c++ - 通过引用传递给模板函数

c++ - 如何使用 Boost 预处理器获取类函数可访问的函数列表?