簡體   English   中英

為什么派生類不能通過指向基類的指針訪問其基類的受保護成員?

[英]Why can a derived class not access a protected member of its base class through a pointer to base?

這是代碼

class TestA
{
protected:
    int test=12;

public:
    TestA() {
        cout << "test a: " << test << endl;
    }
    ~TestA() {
    }
};

class TestB : public TestA
{   
public:
    TestB(TestA *testA) {
        cout << "test b: " << testA->test;
    }
    ~TestB() {
    }
};

int main ()
{
    TestA *pTestA=new TestA();
    TestB *pTestB=new TestB(pTestA);
}

我正在嘗試使用指向TestA類型對象(因此是TestA的實例)的指針來訪問protected的成員。 TestB也是從TestA派生的

為什么我無法訪問它? 它是否只能在我需要的類“內”訪問? 不在使用指針/直接聲明之外?

當public從基類繼承時,它的protected成員成為派生類的protected成員,可以在派生類的成員函數中訪問。 但是它們只能通過派生類本身(及其派生類)訪問,不能通過基類訪問。 所以你不能通過TestA的指針訪問成員test ,但是通過TestB的指針訪問它就可以了。

該標准為此提供了一些說明性示例。 [class.protected]/1

(只保留部分示例代碼)

當非靜態數據成員或非靜態成員函數是其命名類 ([class.access.base])114 的受保護成員時,將應用超出條款 [class.access] 中所述的附加訪問檢查早些時候,由於引用發生在某個類 C 的朋友或成員中,因此授予對受保護成員的訪問權限。如果訪問要形成指向成員 ([expr.unary.op]) 的指針,則嵌套名稱說明符應表示 C 或從 C 派生的類。所有其他訪問都涉及(可能是隱式的)對象表達式([expr.ref])。 在這種情況下,對象表達式的類應為 C 或從 C 派生的類。 [ 示例:

 class B { protected: int i; }; class D1 : public B { }; class D2 : public B { void mem(B*,D1*); }; void D2::mem(B* pb, D1* p1) { pb->i = 1; // ill-formed p1->i = 2; // ill-formed i = 3; // OK (access through this) B::i = 4; // OK (access through this, qualification ignored) }

—結束示例]

我不確定您的設計意圖,讓TestB成為TestA的朋友將是一個簡單的解決方案。

WORLD 類成員可訪問性的概念在這里適用。 WORLD 只能訪問類的公共成員,而不管它們是如何創建/派生的。

考慮下面的例子:

class A
{
    public:
        int public_i;
    protected:
        int protected_i;
    private:
        int private_i;

    public:
        A()
        {
            public_i = 10;
            protected_i = 20;
            private_i = 30;
        }
};

class C : protected A
{
    public:
        void Access(void)
        {
            cout << public_i << endl;
            cout << protected_i << endl;
            //cout << private_i << endl; // <- Not Allowed b'coz its private here
        }
};
class D : private A
{
    public:
        void Access(void)
        {
            cout << public_i << endl;
            cout << protected_i << endl;
            //cout << private_i << endl; // <- Not Allowed b'coz its private here
        }
};
class B : public A
{
    public:
        void Access(D *pd)
        {
            cout << public_i << endl;
            cout << protected_i << endl;
            //cout << private_i << endl; // <- Not Allowed b'coz its private here

            //pd is WORLD here
            //cout << pd->public_i << endl;    // <- Not Allowed b'coz its private here since private inheritance of A by D
            //cout << pd->protected_i << endl; // <- Not Allowed b'coz its protected here
            //cout << pd->private_i << endl; // <- Not Allowed b'coz its private here
        }
};


int main ()
{
    A objA;
    cout << objA.public_i << endl;
    //cout << objA.protected_i << endl; // <- Not Allowed b'coz its protected here
    //cout << objA.private_i << endl;   // <- Not Allowed b'coz its private here

    B objB;
    cout << objB.public_i << endl;
    //cout << objB.protected_i << endl; // <- Not Allowed b'coz its protected here
    //cout << objB.private_i << endl;   // <- Not Allowed b'coz its private here

    C objC;
    //cout << objC.public_i << endl;    // <- Not Allowed b'coz its protected here
    //cout << objC.protected_i << endl; // <- Not Allowed b'coz its protected here
    //cout << objC.private_i << endl;   // <- Not Allowed b'coz its private here

    D objD;
    //cout << objD.public_i << endl;    // <- Not Allowed b'coz its private here
    //cout << objD.protected_i << endl; // <- Not Allowed b'coz its protected here
    //cout << objD.private_i << endl;   // <- Not Allowed b'coz its private here

    //Outside class its all WORLD and WORLD can access only public members.
    //Objects and Pointers are WORLD.

    //Same thing is applicable when class members are accessed via pointers.
    B *pobjB;       //pobjB is WORLD
    cout << pobjB->public_i << endl;
    //cout << pobjB->protected_i << endl; // <- Not Allowed b'coz its protected here
    //cout << pobjB->private_i << endl;   // <- Not Allowed b'coz its private here

    objB.Access(&objD);
    objC.Access();
    objD.Access();

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM