这是code:
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);
}
我正在尝试使用指向protected
类型对象的指针(因此,TestA
的实例)访问TestA
成员。 TestB
也来自TestA
为什么我无法访问它?它只能在我需要它的类中“访问”吗?不在外面使用指针/直接声明?
答案 0 :(得分:7)
当公共从基类继承时,其受保护的成员变为派生类&#39; 保护成员,这些成员可以在派生类中访问&#39;成员职能。但它们只能通过派生类本身(及其派生类)访问,不能通过基类访问。因此,您无法通过test
的指针访问成员TestA
,但可以通过TestB
的指针访问该成员。
该标准为此提供了一些说明性样本。 $11.4/1 Protected member access [class.protected]:
(仅保留示例代码的一部分)
除了前面条款中描述的那些之外的附加访问检查 [class.access]在非静态数据成员或非静态时应用 member function是其命名类的受保护成员 ([class.access.base])114如前所述,访问受保护的 成员被授予,因为引用发生在朋友或成员中 某些类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
的{{1}}朋友成为一个直接的解决方案。
答案 1 :(得分:0)
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;
}