为什么派生成员函数不能访问基类对象的受保护成员? [英] Why can derived member function not access protected member of a baseclass object?
问题描述
如果我通过引用传递基类对象(可能不会在这里通过引用传递
的差异)作为
派生类的参数成员函数,成员函数不允许
访问基础对象的受保护数据成员。这令我惊喜
我。
有人可以解释为什么会这样吗?我怀疑有一个很好的理由和
我只是在一个缓慢的一天不能自己想出来。
Bob
这是一个展示我的意思的示例程序:
// Base.h
#ifndef Base_incl
#define Base_incl
class Derived; //前向声明 - 必需因为Method2()
of Base类引用Derived类
class Base
{
public:
Base(); //构造函数
virtual void Method1(Base&);
virtual void Method2(Base&);
virtual void Method3(Derived&); //将
//派生类对象作为基类
//类方法的参数是不常见的,但正如您所见,它可以完成。
受保护:
int mBase;
};
#endif
// Derived.h
#ifndef Derived_incl
#define Derived_incl
#include" Base.h"
class派生:公共基地
{
公开:
派生( ); //构造函数
virtual void Method2(Base&); //这个方法
//覆盖基类Method2()
virtual void Method4(Base&); //一个新方法
//没有为Base类定义
private:
int mDerived;
};
#endif
// Base.cpp
#include" ; Base.h"
#include" Derived.h"
#include< iostream>
使用std: :cout;
使用std :: endl;
Base :: Base()
{
this-> mBase = 2;
}
void Base :: Method1(Base& B_Param)
{
cout<< (B_Param.mBase)*(this-> mBase)<<结束;
}
void Base :: Method2(Base& B_Param)
{
cout<< this-> mBase<<结束;
}
void Base :: Method3(Derived& D_Param)
{
基地& BRef = static_cast< Base&>(D_Param); //此演员表创建
//对D_Param对象的基类引用。
cout<< BRef.mBase<<结束;
}
//Derived.cpp
#include" Derived.h"
#include< iostream>
使用std :: cout;
使用std :: endl;
派生: :派生()
{
this-> mBase = 3;
this-> mDerived = 5;
}
void Derived :: Method2(Base& B_Param)
{
cout<< this-> mDerived<< endl;
}
void Derived :: Method4(Base& B_Param)
{
派生* DPtr = dynamic_cast< Derived *(& B_Param); //这个演员
//创建一个Derived类指向B_Param的指针,当且仅当,
// B_Param实际上是Derived类对象,否则
//指针将被设置为0
if(DPtr!= 0)//如果B_Param实际上是派生类对象
cout << DPtr-> mDerived<< endl;
else
cout<< B_Param.mBase<< endl;
}
如果我编译Derived.cpp我会收到以下错误:
1> c :\documents and settings\blangela\desktop\polymorphismtest
\ derived.cpp(27):错误C2248:''Base :: mBase'':无法访问
受保护的成员在类''Base'中声明'
1 c:\documents and settings\blangela\desktop\polymorphismtest
\ base .h(17):看到''Base :: mBase'的声明'
1 c:\documents and settings \ blanlala \\\dktop \ polymmorphismtest
\ base.h(7):看到''基地'的声明'
对不起,这是行:
>
cout<< B_Param.mBase<<在下面的成员函数中导致错误的
。
void Derived :: Method4(Base& B_Param)
{
Derived * DPtr = dynamic_cast< Derived *(& B_Param); //这个
cast
//创建一个指向B_Param的派生类指针,如果和
只有,如果,
// B_Param实际上是派生类对象,否则
//指针将被设置为0
if( DPtr!= 0)//如果B_Param实际上是派生类
对象
cout<< DPtr-> mDerived<< endl;
else
cout<< B_Param.mBase<< endl;
}
blangela写道:
如果我通过基地class引用的对象(可能不会在这里通过引用传递一个
的区别)作为
派生类成员函数的参数,成员函数不是允许
访问基础对象的受保护数据成员。这令我惊喜
我。
有人可以解释为什么会这样吗?我怀疑有一个很好的理由和
我只是在一个缓慢的日子里自己没有想出来。
这不是FAQ中的问题吗?它应该是。
简而言之,原因是阻止访问不同类型的成员
(跨层次结构)。如果D1和D2来自B,那么D1
的实例不允许访问D2的任何非公开成员(当然,除非他们是朋友,否则是b $ b朋友)。当您将对B的引用传递给D1的成员
函数时,对该类成员的访问被阻止,因为
它*可以*是D2的子对象对象,而不一定是另一个
D1。需要一个例子吗?看看档案,过去几年我们已经多次讨论了这个话题
。
V
-
请在通过电子邮件回复时删除资金''A'
我没有回复最热门的回复,请不要问
If I pass a base class object by reference (likely does not make a
difference here that it is passed by reference) as a parameter to a
derived class member function, the member function is not allowed to
access the protected data members of the base object. This surprises
me.
Can someone explain why this is? I suspect there is a good reason and
I am just having a slow day to not come up with it myself.
Bob
Here is a sample program to show what I mean:
// Base.h
#ifndef Base_incl
#define Base_incl
class Derived; // forward declaration - required because Method2()
// of the Base class references the Derived class
class Base
{
public:
Base(); // constructor
virtual void Method1(Base &);
virtual void Method2(Base &);
virtual void Method3(Derived &); //it is unusual to have a
// derived class object as a parameter for a base
// class method, but as you see, it can be done.
protected:
int mBase;
};
#endif
// Derived.h
#ifndef Derived_incl
#define Derived_incl
#include "Base.h"
class Derived: public Base
{
public:
Derived(); // constructor
virtual void Method2(Base &); // this method
// overrides Base class Method2()
virtual void Method4(Base &); // a new method
// which is not defined for the Base class
private:
int mDerived;
};
#endif
// Base.cpp
#include "Base.h"
#include "Derived.h"
#include <iostream>
using std::cout;
using std::endl;
Base::Base()
{
this->mBase = 2;
}
void Base::Method1(Base & B_Param)
{
cout << (B_Param.mBase) * (this->mBase) << endl;
}
void Base::Method2(Base & B_Param)
{
cout << this->mBase << endl;
}
void Base::Method3(Derived & D_Param)
{
Base & BRef = static_cast<Base &>(D_Param); // This cast creates
// a Base class reference to the D_Param object.
cout << BRef.mBase << endl;
}
//Derived.cpp
#include "Derived.h"
#include <iostream>
using std::cout;
using std::endl;
Derived::Derived()
{
this->mBase = 3;
this->mDerived = 5;
}
void Derived::Method2(Base & B_Param)
{
cout << this->mDerived << endl;
}
void Derived::Method4(Base & B_Param)
{
Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this cast
// creates a Derived class pointer to B_Param, if and only if,
// B_Param actually is Derived class object, otherwise the
// pointer will be set to 0
if (DPtr != 0) // if B_Param is actually a Derived class object
cout << DPtr->mDerived << endl;
else
cout << B_Param.mBase << endl;
}
If I compile Derived.cpp I get the following errors:
1>c:\documents and settings\blangela\desktop\polymorphismtest
\derived.cpp(27) : error C2248: ''Base::mBase'' : cannot access
protected member declared in class ''Base''
1 c:\documents and settings\blangela\desktop\polymorphismtest
\base.h(17) : see declaration of ''Base::mBase''
1 c:\documents and settings\blangela\desktop\polymorphismtest
\base.h(7) : see declaration of ''Base''
Sorry, it is the line:
cout << B_Param.mBase << endl;
in the member function below that causes the errors.
void Derived::Method4(Base & B_Param)
{
Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this
cast
// creates a Derived class pointer to B_Param, if and
only if,
// B_Param actually is Derived class object, otherwise
the
// pointer will be set to 0
if (DPtr != 0) // if B_Param is actually a Derived class
object
cout << DPtr->mDerived << endl;
else
cout << B_Param.mBase << endl;
}
blangela wrote:If I pass a base class object by reference (likely does not make a
difference here that it is passed by reference) as a parameter to a
derived class member function, the member function is not allowed to
access the protected data members of the base object. This surprises
me.
Can someone explain why this is? I suspect there is a good reason and
I am just having a slow day to not come up with it myself.Isn''t this in the FAQ? It should be.
In short, the reason is to prevent access to members of a different type
(across the hierarchy). If D1 and D2 derive from B, an instance of D1
is not allowed to access any non-public members of D2 (unless they are
friends, of course). When you pass a reference to B to a member
function of D1, the access to members of that class is blocked because
it *can* be a subobject of a D2 object, and not necessarily of another
D1. Need an example? Look in the archives, we had that topic discussed
several times over the past years.
V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask
这篇关于为什么派生成员函数不能访问基类对象的受保护成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!