[心得] 原來繼承不可逆

作者: gecer (gecer)   2017-10-01 10:51:55
#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
原來繼承不可指標逆回上一層
作者: CoNsTaR ((const *))   2017-10-01 11:26:00
這個概念在電腦科學裡叫做 covariance 和 contravariance有一些語言的函數也可以分 super 和 sub 滿有趣的然後 variance 的概念告訴你哪個是哪個的 sub 或 super以及為什麼 super 不能轉 sub,但相反卻可以super 就是你的 base 的意思,sub 就是 child
作者: LPH66 (-6.2598534e+18f)   2017-10-01 18:48:00
NONONO, covariance / contravariance 是繼承鏈類別的衍生出來的型別之間的關係, 這裡只是單純的父指標不能指子而已以此例來說若談論 Base[] D1[] D2[] 的關係或 vector<Base> vector<D1> vector<D2> 的關係這才會用上 *-variance 這個用語
作者: CoNsTaR ((const *))   2017-10-01 21:34:00
指標應該可以看成是一個 type function 吧所以照 c++ 的寫法,D1* 應該可以想成是 *<D1> 之類的東西所以 *<B> 不能直接轉 *<D> 意思就是 B* 不能直接轉 D*至少我是這樣理解為什麼父指標不能直接轉子的喔喔 樓上的意思是只有衍生型別可以用 variance 嗎?那我就不知道了 XDD那如果兩個型別各自從不同型別衍生出來,他們比大小可以用 variance 這個詞嗎?或是如果我說,因為 * 是 covariant 所以 B* 不能轉 D*,這樣講正確嗎?
作者: firose (guest也是也是也是也是也)   2017-10-01 22:57:00
variance 應該是用在繼承上的,在符合 LSP 的前提之下對於函數的傳回值與參數,也可以有繼承關係上的變化
作者: LPH66 (-6.2598534e+18f)   2017-10-02 08:02:00
唔, 把 * 當成 type function 來講嗎...倒是沒這麼思考過; 稍微想一想應該是可以的這樣 * 這個 type function 確實能說是 covariant
作者: Killercat (殺人貓™)   2017-10-02 23:58:00
其實我覺得你想到這case已經滿厲害的了 XD寫一輩子c++都沒想過銜尾蛇

Links booklink

Contact Us: admin [ a t ] ucptt.com