欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 有趣的動態(tài)轉(zhuǎn)換

 更新時(shí)間:2020年09月14日 08:58:10   作者:BianChengNan''''s  
這篇文章主要介紹了c++ 動態(tài)轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和使用c++編程,感興趣的朋友可以了解下

緣起

最近,在項(xiàng)目代碼中看到一個(gè)非常神奇的類型轉(zhuǎn)換—— 類型A 的指針居然能動態(tài)轉(zhuǎn)換成另外一個(gè)完全沒有任何關(guān)系的類指針。這…… 完全顛覆了我的認(rèn)知。

為了進(jìn)一步了解這個(gè)神奇的操作,我特意模擬了項(xiàng)目代碼中的情形,一起來看看吧。

代碼簡介

BaseABaseB 是兩個(gè)基類,NewA 繼承自 BaseA,NewB 繼承自 BaseB。TestB() 會在堆上 new 一個(gè) NewB 的對象,但是會強(qiáng)制轉(zhuǎn)換成 BaseA 類型的指針并返回(這個(gè)操作太逆天,大家一定不要在項(xiàng)目代碼中這么玩兒)。main() 函數(shù)中模擬使用和釋放。背景介紹完畢,看代碼。

測試代碼 1

#include "stdafx.h"
#include "stdlib.h"

class BaseA
{
public:
 virtual void AA() = 0;
 virtual ~BaseA() {};
};

class NewA : public BaseA
{
public:
 ~NewA() { printf(__FUNCTION__ "\n"); }
 virtual void AA() override { printf(__FUNCTION__ "\n"); }
};

class BaseB
{
public:
 virtual void BB() = 0;
 virtual ~BaseB() {};
};

class NewB : public BaseB
{
public:
 virtual ~NewB() { printf(__FUNCTION__ "\n"); }
 virtual void BB() override { printf(__FUNCTION__ "\n"); }
};

BaseA* TestB()
{
 NewB *pNewB = new NewB();
 return (BaseA*)pNewB;
}

int _tmain(int argc, _TCHAR* argv[])
{
 BaseA* pBaseA = TestB();
 BaseB *pBaseB = (BaseB *)pBaseA;

 delete(pBaseA);

 system("pause");
 return 0;
}

上面的代碼有什么問題嗎?運(yùn)行結(jié)果是:一切正常。

but……

測試代碼 2

相對于 測試代碼1,測試代碼2 中調(diào)用了虛函數(shù),只改變了 main 中的調(diào)用部分。

int _tmain(int argc, _TCHAR* argv[])
{
 BaseA* pBaseA = TestB();
 BaseB *pBaseB = (BaseB *)pBaseA;

 // added part: call virtual functions
 pBaseA->AA();
 pBaseB->BB();

 delete(pBaseA);

 system("pause");
 return 0;
}

上面的代碼會輸出什么呢?

pBaseA->AA() 的輸出結(jié)果是 NewB::BB。有些“意外”,但是卻在情理之中。下一篇會比較詳細(xì)的剖析虛函數(shù)調(diào)用機(jī)制,知道運(yùn)作及之后,再回過頭來看這個(gè)問題就很容易理解了!

測試代碼 3

相對于 測試代碼2,測試代碼 3 只為 BaseB 增加了一個(gè)名為 PerfectFunctionName() 的接口,并在子類NewB 中實(shí)現(xiàn)了這個(gè)接口。其它部分不變。這里只列出變化的部分。

#include "stdafx.h"
#include "stdlib.h"

class BaseB
{
public:
 virtual void BB() = 0;
 virtual void PerfectFunctionName() = 0; // Added part
 virtual ~BaseB() {};
};

class NewB : public BaseB
{
public:
 virtual ~NewB() { printf(__FUNCTION__ "\n"); }
 virtual void BB() override { printf(__FUNCTION__ "\n"); }
 virtual void PerfectFunctionName() override { printf(__FUNCTION__ "\n"); } // Added part
};

最新代碼運(yùn)行結(jié)果會是什么樣的呢?

上圖是 32 位 debug 版程序運(yùn)行時(shí)的輸出結(jié)果。終于報(bào)了異常!release 版運(yùn)行后也會報(bào)異常!

從測試結(jié)果可知,這種做法在某些情況下確實(shí)可以正常運(yùn)行,但是某些情況下會得到一些奇怪的結(jié)果,甚至?xí)l(fā)生崩潰。這些現(xiàn)象背后的原因我想留到后面幾篇文章分析。感興趣的小伙伴兒可以手動測試并分析。

結(jié)論

永遠(yuǎn)不要做這種危險(xiǎn)的 SAO 操作!

以上就是c++ 動態(tài)轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于c++ 動態(tài)轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++中strcpy函數(shù)在VS2015無法使用的問題

    c++中strcpy函數(shù)在VS2015無法使用的問題

    這篇文章主要介紹了c++中strcpy函數(shù)在VS2015無法使用的問題,具有一定的參考價(jià)值,有需要的可以了解一下。
    2016-11-11
  • 詳解C語言用malloc函數(shù)申請二維動態(tài)數(shù)組的實(shí)例

    詳解C語言用malloc函數(shù)申請二維動態(tài)數(shù)組的實(shí)例

    這篇文章主要介紹了詳解C語言用malloc函數(shù)申請二維動態(tài)數(shù)組的實(shí)例的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • 詳解C++二叉搜索樹的原理及實(shí)現(xiàn)

    詳解C++二叉搜索樹的原理及實(shí)現(xiàn)

    二叉搜索樹又稱二叉排序樹,二叉搜索樹是一種二叉樹,其中每個(gè)節(jié)點(diǎn)的值大于其左子樹中的任何節(jié)點(diǎn),并且小于其右子樹中的任何節(jié)點(diǎn),本文小編就給大家講講C++二叉搜索樹的操作及實(shí)現(xiàn),感興趣的同學(xué)跟著小編一起來看看吧
    2023-08-08
  • opencv車道線檢測的實(shí)現(xiàn)方法

    opencv車道線檢測的實(shí)現(xiàn)方法

    這篇文章主要介紹了opencv車道線檢測的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 原碼, 反碼與補(bǔ)碼基礎(chǔ)知識詳細(xì)介紹

    原碼, 反碼與補(bǔ)碼基礎(chǔ)知識詳細(xì)介紹

    這篇文章講解了計(jì)算機(jī)的原碼, 反碼和補(bǔ)碼. 并且進(jìn)行了深入探求了為何要使用反碼和補(bǔ)碼, 以及更進(jìn)一步的論證了為何可以用反碼, 補(bǔ)碼的加法計(jì)算原碼的減法,需要的朋友可以參考下
    2016-12-12
  • 利用簡潔的C語言代碼解決跳臺階問題與約瑟夫環(huán)問題

    利用簡潔的C語言代碼解決跳臺階問題與約瑟夫環(huán)問題

    這篇文章主要介紹了利用簡潔的C語言代碼解決跳臺階問題與約瑟夫環(huán)問題的方法,跳臺階問題與約瑟夫環(huán)問題是常見的基礎(chǔ)算法題目,需要的朋友可以參考下
    2016-02-02
  • 淺談C++中派生類對象的內(nèi)存布局

    淺談C++中派生類對象的內(nèi)存布局

    下面小編就為大家?guī)硪黄獪\談C++中派生類對象的內(nèi)存布局。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • 簡單的socket編程入門示例

    簡單的socket編程入門示例

    這篇文章主要介紹了簡單的socket編程入門示例,簡單實(shí)現(xiàn)client輸入內(nèi)容發(fā)送到server端輸出,需要的朋友可以參考下
    2014-03-03
  • 詳解C語言如何計(jì)算結(jié)構(gòu)體大小(結(jié)構(gòu)體的內(nèi)存對齊)

    詳解C語言如何計(jì)算結(jié)構(gòu)體大小(結(jié)構(gòu)體的內(nèi)存對齊)

    結(jié)構(gòu)體的內(nèi)存對齊是有關(guān)結(jié)構(gòu)體內(nèi)容的很重要一個(gè)知識點(diǎn),主要考察方式是計(jì)算結(jié)構(gòu)體的字節(jié)大小,所以本文就給大家詳細(xì)介紹一下C語言如何計(jì)算結(jié)構(gòu)體大小,文中的代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • C語言結(jié)構(gòu)體指針的具體使用

    C語言結(jié)構(gòu)體指針的具體使用

    結(jié)構(gòu)體指針是一種非常有用的數(shù)據(jù)類型,它可以讓我們更方便地操作結(jié)構(gòu)體,本文主要介紹了C語言結(jié)構(gòu)體指針的具體使用,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2023-05-05

最新評論