C++指針漂移問題解決方案
C++編程語言雖然功能強(qiáng)大,應(yīng)用方式靈活,但是在實際編程中同樣會出現(xiàn)各種各樣的錯誤。在這里我們將會為大家詳細(xì)介紹一下有關(guān)C++指針漂移的解決方法,希望本文介紹的內(nèi)容可以幫助大家解決問題。
最近我們在工作中碰到一個奇怪的問題,***確定是多繼承引起的C++指針漂移,跟C++對象模型有關(guān)。示意如下:
- class A {...};
- class B{...};
- class AB : public B, public A {...}
- ...
- AB *pab = new AB();
- A* pa = (A*)pab;
- B* pb = (B*)pab;
這時候你發(fā)現(xiàn)pa和pb的值是不一樣的!它們中有一個跟pab是相等的,而另外一個產(chǎn)生了偏移。如果把AB的聲明中A和B的順序調(diào)換一下,則產(chǎn)生偏移的指針也會變?yōu)榱硗庖粋€。
為了確定這是編譯器做了轉(zhuǎn)換的緣故,利用void指針愚弄編譯器:
- void *pv = (void*)pab;
- pa = (A*)pv;
這時候pa的值倒是跟pab相等了,然而指向了錯誤的地方。從pab到pa的轉(zhuǎn)換,依賴于路徑的選擇,讓人不是很放心。還不知道把指針放入容器中再取出來,會不會出錯。當(dāng)然,上面使用了強(qiáng)制類型轉(zhuǎn)換,在良好的程序中應(yīng)該避免。如果只有隱式轉(zhuǎn)換,可以得到正確的結(jié)果:
- std::vector<A*> v;
- //implicit type conversion
- v.insert(v.begin(), pab);
- void *pv = v[0];
- pa = (A*)pv;
以下程序使用Cygwin/g++b編譯通過:
- #include <stdio.h>
- #include <vector>
- class A
- {
- public:
- int a;
- };
- class B
- {
- public:
- int b;
- };
- class AB : public B, public A
- {
- public:
- int ab;
- };
- int main(int argc, char **argv)
- {
- AB *pab = new AB();
- pab->ab = 1;
- pab->b = 2;
- pab->a = 3;
- A* pa = (A*)pab;
- B* pb = (B*)pab;
- printf( "AB: %p\n" \
- " A: %p\n" \
- " B: %p\n",
- pab, pa, pb);
- std::vector<A*> v;
- //implicit type conversion
- v.insert(v.begin(), pab);
- void *pv = v[0];
- pa = (A*)pv;
- printf("pv is %p\npa is %p\npab %s pv\n", pv, pa, (pab == pv)
? "==" : "!=");- printf("A.a is %d\n", pa->a);
- //forced type conversion
- pv = (void*)pab;
- pa = (A*)pv;
- printf("Now A.a is %d\n", pa->a);
- }
運行結(jié)果:
- AB: 0x6b01f0
- A: 0x6b01f4
- B: 0x6b01f0
- pv is 0x6b01f4
- pa is 0x6b01f4
- pab != pv
- A.a is 3
- Now A.a is 2
以上就是C++指針漂移的相關(guān)解決方法。
【編輯推薦】