[英]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.