为什么派生成员函数不能访问基类对象的受保护成员? [英] Why can derived member function not access protected member of a baseclass object?

查看:294
本文介绍了为什么派生成员函数不能访问基类对象的受保护成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我通过引用传递基类对象(可能不会在这里通过引用传递

的差异)作为

派生类的参数成员函数,成员函数不允许
访问基础对象的受保护数据成员。这令我惊喜

我。


有人可以解释为什么会这样吗?我怀疑有一个很好的理由和

我只是在一个缓慢的一天不能自己想出来。


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆