之前學習c/c++的時候一直都認為型別轉換(不管是顯式的還是隱式的)其實什麼都沒有做,只是告訴編譯器型別改變了一下,讓它的翻譯記憶體二進位制資料的時候以新型別的套路去翻譯而已。
然而當我看到effective c++ rule 27.關於轉型動作會觸發其它動作時,我是很驚訝的。
先貼出一段**來看看,轉型並不是什麼都沒有做,相反,它做了很多事情,我們一一來看。
#include
#include
class super1
super1(const super1& rhs)
virtual ~super1()
virtual
void display()
void hello()
};class super2
void display()
};class derived:
public super1,public super2
};int main()
**不複雜,有兩個基類:super1和super2.
有乙個繼承類:derived ,多繼承自super1和super2.
main函式內部,也就是簡單的取位址,並將子類的位址轉換為基類位址。
猜猜會列印出來什麼呢?
如果是在以前,我肯定會認為 sp1,sp2,child這三個值是一樣的。
然而:
輸出為:
6ffd58 6ffd60 6ffd58
sp2 比sp1向高位址偏移了8個位元組(super1 內部有乙個4個位元組的num,還有乙個4位元組的vtable指標,因為類裡面有虛函式)。而child與sp1相同的。
這不禁讓我去思考,轉型cast 是什麼東西?它究竟是如何實現的?
轉型可以分為兩大類:物件轉型和指標轉型(包括引用轉型)
物件轉型的行為看起來就類似於呼叫類的建構函式來生成物件。如果發現沒有適當的建構函式用來呼叫,那麼就會轉型失敗。
例如還是上面的**:
#include
#include
class super1
super1(const super1& rhs)
virtual ~super1()
virtual
void display()
void hello()
};class super2
void display()
};class derived:
public super1,public super2
};int main()
在子類的display函式內部:
我們企圖去呼叫父類 super1的函式display.
但是我們卻寫出了:(super1 (*this)).display()這樣的**。
我們看到 super1(*this) 這個呼叫形式是不是就剛好匹配了複製建構函式super1(const super1& )?沒錯!上面這個過程,實際上會先用*this的內容生成乙個super1 類的匿名例項,然後再呼叫這個匿名例項的display()方法。
我們看看輸出:
call super1(const super1 & rhs).
here is super1, the num is
1 (50fb28)
call ~super1()
here is
derived
class, the num is num1 1(50fd10) and num2 -858993460(50fd18) .
50fd0c 50fd14 50fd0c
可以看到 前三行都是那個super1類的匿名物件,這個物件與子類child內部的super1是不同的!
這可能與我們想要的有些出入,因為我們寫出(super1 (*this)).display() 是想父類的display指標能夠展示當前物件this的num1的內容,而不是想要去重新生成乙個super1物件。這個情況還不算特殊,因為這只是在讀取num1的內容。
更特殊的是 display的內部邏輯可能會修改num1的值,那麼這種呼叫方式下父類display函式對num1的修改 實際上是不會影響到this物件的num1的值的。因為它們本來就存在不同的記憶體區域。
實際上,我們想實現的是:
virtual void display()
這種效果,這種實現方式下,display都是對當前this物件的num1進行讀取。
同樣的:
int num=1
double num2=(double)num/3;
其實內部的執行過程是:生成乙個匿名double,並用num的值去初始化這個匿名物件,然後這個匿名物件在參與運算。
那麼指標間的轉型又是怎麼完成的呢?
個人猜測過程也是類似的,也是呼叫某類指標的複製建構函式去生成乙個匿名指標物件,但是這種建構函式不是由程式設計師編寫的,而是由編譯器自動生成的,程式設計師無法控制,而且不同的編譯器還會有不同的操作。此類建構函式在內部實現中很可能會根據引數的不同,做一些指標的偏移、變換操作,尤其是使用多重繼承的時候。
(2 2)訊號的概念,認識,處理動作
程序之間的常用通訊手段 傳送訊號,kill 第二章第二節講過 上節課討論過 sighup 訊號 通知 事情通知 用來通知某個程序發生了某乙個事情 事情,訊號都是突發事件,訊號是非同步發生的,訊號也被稱呼為 軟體中斷 訊號如何產生 a 某個程序傳送給另外乙個程序或者傳送給自己 b 由核心 作業系統 傳...
3 3 訊號的概念 認識 處理動作
程序之間的常用通訊手段 傳送訊號,kill 第二章第二節講過 上節討論過 sighup 訊號 通知 事情通知 用來通知某個程序發生了某乙個事情 事情,訊號都是突發事件,訊號是非同步發生的,訊號也被稱呼為 軟體中斷 訊號如何產生 a 某個程序傳送給另外乙個程序或者傳送給自己 b 由核心 作業系統 傳送...
const的新認識
今天發現乙個有趣的現象,有如下 void fun char p int main void fun char p 和c d這兩行會出現waring 其實這兩行都是相同的賦值語句,都是有const修飾的賦值給沒有const修飾的。也就是說只能把沒有const修飾的賦值給有const修飾的,反之則war...