[心得] 原來繼承不可逆

看板C_and_CPP作者 (gecer)時間8年前 (2017/10/01 10:51), 8年前編輯推噓8(8020)
留言28則, 4人參與, 最新討論串1/1
#include <iostream> using namespace std; class Base { public: virtual void function1() {cout<<"Base :: function1()\n";}; virtual ~Base(){}; }; class D1: public Base { public: ~D1(){}; void function1() { cout<<"D1 :: function1()\n";}; }; class D2: public D1 { public: ~D2(){}; void function1() { cout<<"D2 :: function1()\n";}; }; int main() { D2 *d2=new D2; D1 *d1=new D1; Base *b=new Base; D1 *dd; dd=d2; dd->function1(); dd=d1; dd->function1(); dd=b; dd->function1(); return (0); } 小弟先定義class Base->繼承給D1->繼承給D2 then 宣告D1 *dd 指標給各class 當dd指標Base(dd=b)時 compiler 便會出現 error: invalid conversion from 'Base*' to 'D1*' [-fpermissive 原來繼承不可指標逆回上一層 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.255.30.171 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1506826318.A.2B3.html ※ 編輯: gecer (111.255.30.171), 10/01/2017 10:52:49 ※ 編輯: gecer (111.255.30.171), 10/01/2017 10:54:27

10/01 11:26, , 1F
這個概念在電腦科學裡叫做 covariance 和 contravariance
10/01 11:26, 1F

10/01 11:26, , 2F
有一些語言的函數也可以分 super 和 sub 滿有趣的
10/01 11:26, 2F

10/01 11:29, , 3F
然後 variance 的概念告訴你哪個是哪個的 sub 或 super
10/01 11:29, 3F

10/01 11:29, , 4F
以及為什麼 super 不能轉 sub,但相反卻可以
10/01 11:29, 4F

10/01 11:30, , 5F
super 就是你的 base 的意思,sub 就是 child
10/01 11:30, 5F

10/01 18:48, , 6F
NONONO, covariance / contravariance 是繼承鏈類別的衍生
10/01 18:48, 6F

10/01 18:49, , 7F
出來的型別之間的關係, 這裡只是單純的父指標不能指子而已
10/01 18:49, 7F

10/01 18:49, , 8F
以此例來說若談論 Base[] D1[] D2[] 的關係
10/01 18:49, 8F

10/01 18:50, , 9F
或 vector<Base> vector<D1> vector<D2> 的關係
10/01 18:50, 9F

10/01 18:50, , 10F
這才會用上 *-variance 這個用語
10/01 18:50, 10F

10/01 21:34, , 11F
指標應該可以看成是一個 type function 吧
10/01 21:34, 11F

10/01 21:34, , 12F
所以照 c++ 的寫法,D1* 應該可以想成是 *<D1> 之類的東
10/01 21:34, 12F

10/01 21:34, , 13F
西
10/01 21:34, 13F

10/01 21:34, , 14F
所以 *<B> 不能直接轉 *<D> 意思就是 B* 不能直接轉 D*
10/01 21:34, 14F

10/01 21:34, , 15F
至少我是這樣理解為什麼父指標不能直接轉子的
10/01 21:34, 15F

10/01 21:44, , 16F
喔喔 樓上的意思是只有衍生型別可以用 variance 嗎?
10/01 21:44, 16F

10/01 21:44, , 17F
那我就不知道了 XDD
10/01 21:44, 17F

10/01 21:44, , 18F
那如果兩個型別各自從不同型別衍生出來,他們比大小可以
10/01 21:44, 18F

10/01 21:44, , 19F
用 variance 這個詞嗎?
10/01 21:44, 19F

10/01 22:01, , 20F
或是如果我說,因為 * 是 covariant 所以 B* 不能轉 D*,
10/01 22:01, 20F

10/01 22:01, , 21F
這樣講正確嗎?
10/01 22:01, 21F

10/01 22:57, , 22F
variance 應該是用在繼承上的,在符合 LSP 的前提之下
10/01 22:57, 22F

10/01 22:57, , 23F
對於函數的傳回值與參數,也可以有繼承關係上的變化
10/01 22:57, 23F

10/02 08:02, , 24F
唔, 把 * 當成 type function 來講嗎...
10/02 08:02, 24F

10/02 08:02, , 25F
倒是沒這麼思考過; 稍微想一想應該是可以的
10/02 08:02, 25F

10/02 08:03, , 26F
這樣 * 這個 type function 確實能說是 covariant
10/02 08:03, 26F

10/02 23:58, , 27F
其實我覺得你想到這case已經滿厲害的了 XD
10/02 23:58, 27F

10/02 23:58, , 28F
寫一輩子c++都沒想過銜尾蛇
10/02 23:58, 28F
文章代碼(AID): #1Pq5XEAp (C_and_CPP)