我很困惑:我想保护的数据是在C中某一类++的孩子读/写。
以下代码段失败在MS的编译器编译
class A
{
protected:
int data;
};
class B : public A
{
public:
B(A &a)
{
data = a.data;
}
};
int main()
{
A a;
B b = a;
return 0;
}
错误信息:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
demoFail.cpp
demoFail.cpp(12) : error C2248: 'A::data' : cannot access protected member declared in class 'A'
demoFail.cpp(4) : see declaration of 'A::data'
demoFail.cpp(2) : see declaration of 'A'
我究竟做错了什么?
根据TC ++ PL,皮克404:
派生类可以访问一个基类的受保护成员仅针对其自身的类型的对象....这防止当一个派生类腐化数据属于其他派生类,否则将发生细微的错误。
当然,这里有个简单的方法来解决这一问题为你的情况:
class A
{
protected:
int data;
};
class B : public A
{
public:
B(const A &a)
: A(a)
{
}
};
int main()
{
A a;
B b = a;
return 0;
}
C ++标准说,关于保护非静态成员在11.5/1
当朋友或派生类的成员函数的引用的受保护非静态成员函数或基类的保护的非静态数据成员,访问检查应用于除了那些在前面条款11所述的用于形成指针构件时除(5.3 0.1),则访问必须通过一个指针,参考,或对象的派生类本身(或从该类派生的任何类)(5.2.5)的。 如果访问是要形成一个指针构件,所述嵌套名称说明符应命名派生类(或从该类派生的任何类)。
除了由别人(的构造函数前面提到的固定的东西B
是私有的),我认为rlbond的方式会做的罚款。 然而,标准的上述段落的一个直接后果是以下是可能用构件指针,可论证是在类型系统中的孔,当然
class B : public A {
public:
B(A &a){
int A::*dataptr = &B::data;
data = a.*dataptr;
}
};
当然,不推荐使用此代码做的,但表明你可以访问它,如果你真的需要(我已经看到了这种方式被用于打印出std::stack
, std::queue
, std::priority_queue
通过访问其受保护的容器构件c
)
你刚才不应该复制A
在对象B
构造。 其目的是初始化留下A
的成员,它自己的构造函数:
struct A {
A( const A& a ): data( a.data ) {}
protected: int data;
};
struct B : public A {
B( const A& a ): A( a ) {}
};
B的构造函数是私有的。 如果没有指定任何东西,在一个类中,默认修饰符是私有的(对于结构它是公共的)。 因此,在这个例子中,问题是,你不能构造B.当您添加市民构造器乙anoter问题出现了:
B在这种情况下,修改的部分从派生而不是另一个像一个向右。
你可以做如下:
class A
{
public:
A()
: data(0)
{
}
A(A &a)
{
data = a.data;
}
protected:
int data;
};
class B : public A
{
public:
B(A &a)
: A(a)
{
}
};
int main()
{
A a;
B b = a;
return 0;
}