爲什麼我在此代碼得到:轉換** const int的**
void foo (const int **);
int main() {
int ** v = new int * [10];
foo(v);
return 0;
}
此錯誤:
invalid conversion from ‘int**’ to ‘const int**’ [-fpermissive]|
我認爲這將有可能從非const轉換const。
爲什麼我在此代碼得到:轉換** const int的**
void foo (const int **);
int main() {
int ** v = new int * [10];
foo(v);
return 0;
}
此錯誤:
invalid conversion from ‘int**’ to ‘const int**’ [-fpermissive]|
我認爲這將有可能從非const轉換const。
那是因爲你正試圖轉換從int** to 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
總是,只是使用上述過程。
而且也:
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 = ⊂
*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++的指針混淆解析規則。這可能是更清楚的看是這樣的:
typedef const int * ptr_to_const_int;
void foo(ptr_to_const_int *);
int main() {
int ** v = new int * [10];
foo(v);
return 0;
}
什麼FOO()參數列表的承諾是,你的指針被傳遞到(指針到恆定的東西)。但是新的int * [10]的意思是「指針指向不是常量的指針」。
所以,如果富被這樣定義:
foo(const int **p)
{
(*p); //<-- this is actually of type const int *
}
而我想你期待的是
foo(const int **p)
{
(*p); //<-- you're expecting this to be of type int *
p = 0; //<-- and this to throw a compiler error because p is const
}
,但它不是,你聲明爲常數P,它的東西它指向。
無論如何,只要在這種情況下使用typedef,一切都將清晰可讀。
只能在similiar指針類型之間的轉換,如果你添加常數各級從CV的第一個區別添加常量資格資格和起來。
因此,您可以將int**
轉換爲int const* const*
,但不能轉換爲int const* *
。如果允許省略在中間水平增加常量,你將能夠做這樣的事情:
const int c = 29;
int *pi;
const int** ppci = π // only adding const, right
*ppci = &c;
*pi = 0; // changing c ?! but no const_cast in sight
如果foo的原型就是它會被允許:'無效美孚(INT * const的*)' – IronMensan 2013-05-05 23:50:54
我得到'那麼對'foo(int * const *)'的未定義引用。 – user1170330 2013-05-05 23:53:49
您是否也在'foo'的定義中更改了類型? – 2013-05-05 23:54:28