访问派生类中的受保护成员

我昨天遇到了一个错误,虽然很容易解决,但我想确保我正确地理解了 C + + 。

我有一个带有受保护成员的基类:

class Base
{
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};

这样就可以很好地编译和工作了。现在我扩展 Base,但是仍然想使用 b:

class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};

注意,在这种情况下,DoSomething仍然接受对 Base的引用,而不是对 Derived的引用。我希望我仍然可以访问 Derived内部的 that.b,但是我得到了一个 cannot access protected member错误(MSVC 8.0-还没有尝试 gcc)。

显然,在 b上添加一个公共 getter 解决了这个问题,但是我想知道为什么我不能直接访问 b。我认为当您使用公共继承时,受保护的变量对于派生类仍然是可见的。

107207 次浏览

类只能访问此类或派生类的实例的受保护成员。它不能访问父类或表亲类的实例的受保护成员。

在您的示例中,Derived类只能访问 Derived实例的受 b保护的成员,而不能访问 Base实例的成员。

更改构造函数以获取 Derived实例将解决这个问题。

您可以访问 Derived的受保护成员,但是不能访问 Base的受保护成员(即使它是 Derived的受保护成员的唯一原因是因为它是从 Base继承的)

如前所述,这只是语言的工作方式。

另一个解决方案是利用继承并传递给父方法:

class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};

使用 this指针访问受保护的成员

class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
this->b+=that.b;
d=0;
}
};

可以访问 protected成员:

  • 通过 this指针
  • 或同一类型的受保护成员,即使声明在基
  • 或者来自好友类、函数

要解决您的情况,您可以使用最后两个选项之一。

接受派生在派生: : DoSomething 或声明派生 friend到基:

class Derived;


class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};


class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};

在某些情况下,您还可以考虑使用公共 getter。

class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};


//this will work

你可以试试 Static _ cast < const Derived * > (pBase)-> Base: : protected _ member..。

class Base
{
protected:
int b;


public:
...
};


class Derived : public Base
{
protected:
int d;


public:
void DoSomething(const Base& that)
{
b += static_cast<const Derived*>(&that)->Base::b;
d=0;
}
void DoSomething(const Base* that)
{
b += static_cast<const Derived*>(that)->Base::b;
d=0;
}
};

黑进 STL之后,我编写了一个小代码,它似乎解决了访问派生类中受保护成员的问题

#include <iostream>


class B
{
protected:
int a;
public:
void dosmth()
{
a = 4;
}


void print() {std::cout<<"a="<<a<<std::endl;}
};


class D: private B
{
public:
void dosmth(B &b)
{
b.*&D::a = 5;
}
};


int main(int argc, const char * argv[]) {


B b;
D d;
b.dosmth();
b.print();
d.dosmth(b);
b.print();


return 0;
}


指纹

a=4
a=5