Conversion from int** to const int**(从 int** 到 const int** 的转换)
问题描述
为什么我会进入这个代码:
Why do I get in this code:
void foo ( const int ** );
int main() {
    int ** v = new int * [10];
    foo(v);
    return 0;
}
这个错误:
invalid conversion from ‘int**’ to ‘const int**’ [-fpermissive]|
我认为可以从非常量转换为常量.
I thought it would be possible to convert from non-const to const.
推荐答案
那是因为你试图从 int** 转换为 const int**
int ** v = new int * [10]; // v is int**
foo(v); //but foo takes const int**
int **是:指向整数指针的指针".const int **是:一个指向常量整数指针的指针".int **is: "a pointer to a pointer to an integer".const int **is: "a pointer to a pointer to a constant integer".
const 的使用是一个契约,你不能通过两个引用的间接来满足这个契约.
The use of const is a contract and you cannot meet this contract by going through the indirection of two references.
来自标准:
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 总是,只需使用上面的过程.
so it would be possible to modify const char always, just use procedure above. 
还有:
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* 指向不同派生类的对象,这可能会导致严重的问题.看看为什么:
related to this is also invalid conversion Derived** → Base**. If it were legal to convert Derived** → Base**, the Base** could be dereferenced (yielding a Base*), and the Base* could be made to point to an object of a different derived class, which could cause serious problems. See why:
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
");}
  virtual void openGasCap(){printf("Car: open gas cap
");}
    virtual void openGasCap2(){printf("Car: open gas cap2
");}
      virtual void openGasCap3(){printf("Car: open gas cap3
");}
            virtual void openGasCap4(){printf("Car: open gas cap4
");}
}; 
class NuclearSubmarine : public Vehicle {
public:
    int i;
  virtual void startEngine(){printf("Nuclear submarine engine brummm
");}
    virtual void fireNuclearMissle3(){printf("Nuclear submarine: fire the missle3!
");}
    virtual void fireNuclearMissle(){printf("Nuclear submarine: fire the missle!
");}
  virtual void fireNuclearMissle2(){printf("Nuclear submarine: fire the missle2!
");}
};   
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 = ⊂
  *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 
}
                        这篇关于从 int** 到 const int** 的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 int** 到 const int** 的转换
				
        
 
            
        基础教程推荐
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
 - 如何通过C程序打开命令提示符Cmd 2022-12-09
 - 在 C++ 中计算滚动/移动平均值 2021-01-01
 - 如何检查GTK+3.0中的小部件类型? 2022-11-30
 - 我有静态或动态 boost 库吗? 2021-01-01
 - 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
 - C++结构和函数声明。为什么它不能编译? 2022-11-07
 - 这个宏可以转换成函数吗? 2022-01-01
 - 如何在 C++ 中初始化静态常量成员? 2022-01-01
 - 常量变量在标题中不起作用 2021-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				