1. 程式人生 > >關於類的虛擬函式的public,private的繼承問題。

關於類的虛擬函式的public,private的繼承問題。

下面的程式碼編譯結果報錯。

test.c: In function `int main(int, char**)':
test.c:18:22: error: `virtual void TEST2::testxiongyf()' is private
test.c:60:25: error: within this context
但是看60行。

如果把private切換為public,你會發現。

 k4->testxiongyf();實際上呼叫的是TEST類的虛擬函式,是public的。

也就是編譯器對於私有公有的,沒有一個整體的掃描。從k4發現是TEST2的。所以就認為是要呼叫TEST2的虛擬函式,

所以導致編譯導致說出錯。

可以認為是編譯器的小BUG,或者說編譯器就是如此設計,免得繁瑣。

那如何會避免出現編譯錯誤呢?強制轉換型別看看。

((TEST *)k4)->testxiongyf();

發現,確實可以編譯過了!!。而且如果把紅色字型部分開啟,可以看出可以呼叫到private的回撥,多型性也能體現。

說到底,欺騙編譯器或者說規避編譯器的坑。

這種測試只是為了學習實驗,不是在實際中這樣用。

在實踐中,也經常看到。如果虛擬函式被定義為PRIVATE,只要基類的是PUBLIC,也可以而且允許通過基類間接訪問到。

#include "stdio.h"

class TEST
{

        int  a;
        int  b;
        public :
        virtual void testxiongyf()
        {
                printf("test111\n");
        }
};


class TEST2:public TEST
{
        private:
        virtual void testxiongyf()
        {
                printf("test222\n");

        }

};


int test(TEST *AA)
{
//      AA.testxiongyf();
        AA->testxiongyf();
        (*AA).testxiongyf();
}


int  main(int argc,char *argv[] )
{
        TEST k3;
        TEST2 k2;
        TEST *k1=&k2;
        TEST2 *k4;
        TEST *k5;

        printf("%d\n");

        k1->testxiongyf();
        k3= *(TEST*)&k2;
        k4=(TEST2 *)&k3;
        k3.testxiongyf();

        (&k3)->testxiongyf();
        //*(int *)&k3=*(int*)&k2;

        (&k3)->testxiongyf();
        k5=&k3;
        k5->testxiongyf();
        k3.testxiongyf();
        printf("k3 %x,k4 %x\n",&k3,k4);

        k4->testxiongyf();
//        (*k4).testxiongyf();

//      test(&k3);

}