[英]Why can't my object access protected members of another object defined in common base class?
The following code produces a compiler error: 以下代码产生编译器错误:
'BaseTest::_protMember' : cannot access protected member declared in class 'BaseTest' 'BaseTest :: _ protMember':无法访问在类'BaseTest'中声明的受保护成员
Why can't I access the member variable _protMember
in my class SubTest
even though it is protected? 为什么即使我的class SubTest
受保护,也无法访问成员变量_protMember
?
class BaseTest
{
public:
BaseTest(){};
BaseTest(int prot)
{
_protMember = prot;
};
protected:
int _protMember;
};
class SubTest : public BaseTest
{
// followup question
SubTest(const SubTest &subTest)
{
_protMember = subTest._protMember; // this line compiles without error
};
SubTest(const BaseTest &baseTest)
{
_protMember = baseTest._protMember; // this line produces the error
};
};
Followup question: 后续问题:
Why is it, that in the added copy constructor I can access protected members of another instance? 为什么会这样,在添加的副本构造函数中我可以访问另一个实例的受保护成员 ?
You can only access protected
members from your own base class instance... not one provided to you as a parameter. 您只能从自己的基类实例访问protected
成员,而不能作为参数提供给您。 It's all about OO encapsulation really. 实际上,所有这些都是关于OO封装的。 Without this restriction, the object under construction could invalidate invariants of the baseTest&
parameter. 没有此限制,正在构造的对象可能会使baseTest&
参数的不变式无效。
Put another way, your SubTest
may decide on a use for a protected
member that conflicts with the usage made of the same member by another BaseTest
-derived class (say SubTest2 : BaseTest
). 换句话说,您的SubTest
可能会决定对protected
成员的使用与另一BaseTest
派生的类对同一成员的使用产生冲突(例如SubTest2 : BaseTest
)。 If your SubTest
code was allowed to fiddle with the other object's data, it could invalidate the invariants in a SubTest2
object, or get some values out that were - in the intended encapsulation - only meant to be exposed to SubTest2
and (optionally - see below) SubTest2
derivatives. 如果您的SubTest
代码被允许摆弄另一个对象的数据,那么它可能会使SubTest2
对象中的不变量无效,或者得到某些值-在预期的封装中-仅打算公开给SubTest2
并且(可选-参见下文) ) SubTest2
衍生产品。
Followup question: Why is it, that in the added copy constructor I can access protected members of another instance? 后续问题:为什么在添加的副本构造函数中我可以访问另一个实例的受保护成员?
SubTest(const SubTest& x); // can access x._protMember
SubTest(const BaseTest& x); // cannot access x._protMember
The same insights above explain why this is allowed: the copy constructor gets a SubTest&
rather than just any old object derived from BaseTest
, and this constructor is clearly within the SubTest
abstraction. 上面相同的见解解释了为什么允许这样做:复制构造函数获取SubTest&
而不仅仅是从BaseTest
派生的任何旧对象,并且此构造函数显然在SubTest
抽象内。 The SubTest
coder is assumed to be conversant with the intended design/encapsulation SubTest
provides, and the copy constructor is given access to bypass and enforce post-conditions/invariants on the other SubTest&
object too. 假定SubTest
编码器熟悉SubTest
的预期设计/封装,并且复制构造函数也被授予访问权限,并且可以绕过另一个SubTest&
对象并对其执行后置条件/不变式。 (You are copying from an object that might itself have been copy-constructed by the very same function, so protecting it when on the " *this
" side but not the parameter-by-ref side isn't much protection at all, even ignoring all the sound reasons you may want/need that access). (您正在从本身可能已经由相同功能复制构造的对象中进行复制,因此在“ *this
”侧而不是由“按引用引用”参数侧进行保护根本就没有太多保护,甚至忽略您可能想要/需要该访问权限的所有声音原因)。
It is possible that a SubTest
-derived object will be accidentally passed to the SubTest
copy constructor ("slicing"), but even for that scenario the SubTest&
class can control whether the further-derived object could have been doing anything unexpected with _protMember
- adding a private
using BaseTest::_protMember;
SubTest
派生的对象很可能会意外地传递给SubTest
复制构造函数(“切片”),但是即使在这种情况下, SubTest&
类也可以控制是否使用_protMember
做其他意外的_protMember
-添加using BaseTest::_protMember;
的private
using BaseTest::_protMember;
statement if it wants to "finalise" access to _protMember
and forbid any derived classes from using it. 语句是否要“完成”对_protMember
访问并禁止任何派生类使用它。
You can access protected
members only in the class instance. 您只能在类实例中访问protected
成员。 That is : 那是 :
class SubTest : public BaseTest
{
SubTest(const BaseTest &baseTest)
{
_protMember = baseTest._protMember;
// ^^^^^^^^^^^ Is good because you are in the instance of its class
_protMember = baseTest._protMember;
// ^^^^^^^^^^^^^^^^^^^^^ Produce error because you are not in the baseTest instance.
};
// followup question
SubTest(const SubTest &subTest)
{
_protMember = subTest._protMember;
// Compile because access modifiers work on class level, and not on object level.
};
};
EDIT for the followup : 编辑后续:
The access modifiers work on class level, and not on object level. 访问修饰符在类级别而不在对象级别起作用。
That is, two objects of the same class can access each others private members. 即,同一类的两个对象可以互相访问私有成员。
This is my source : Why can I access private variables in the copy constructor? 这是我的来源: 为什么我可以在复制构造函数中访问私有变量?
By defining _protMember
as protected
you allow objects of derived classes to access their own _protMember
. 通过将_protMember
定义为protected
您可以允许派生类的对象访问其自己的 _protMember
。 This does not mean all objects of derived classes can access _protMember
of other objects. 这并不意味着派生类的所有对象都可以访问其他对象的_protMember
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.