C++ 派生类无法访问基类的受保护成员

C++ 派生类无法访问基类的受保护成员,c++,class,inheritance,protected,C++,Class,Inheritance,Protected,考虑下面的例子 class base { protected : int x = 5; int(base::*g); }; class derived :public base { void declare_value(); derived(); }; void derived:: declare_value() { g = &base::x; } derived::derived() :base() {} 据了解,只有基类的朋友和派生类

考虑下面的例子

class base
{
protected :
    int x = 5;
    int(base::*g);
};
class derived :public base
{
    void declare_value();
    derived();
};
void derived:: declare_value()
{
    g = &base::x;
}
derived::derived()
    :base()
{}
据了解,只有基类的朋友和派生类可以访问基类的受保护成员,但在上面的示例中,我得到以下错误
“error C2248'base::x”:无法访问类中声明的受保护成员“
,但当我添加以下行时

friend class derived;

将其声明为friend,我可以访问基类的成员,我在声明派生类时是否犯了一些基本错误?

派生类只能通过派生类的上下文访问基类的成员。换句话说,派生类不能通过基类访问受保护的成员

形成指向受保护成员的指针时,它必须使用派生的 类别在其声明中:

struct Base {
 protected:
    int i;
};

struct Derived : Base {
    void f()
    {
//      int Base::* ptr = &Base::i;    // error: must name using Derived
        int Base::* ptr = &Derived::i; // okay
    }
};
你可以改变

g = &base::x;


我的编译器实际上说我需要向
base
添加一个非默认构造函数,因为该字段没有初始化

在我加上

base() : g(&base::x) {}

它编译起来没有问题。

好吧,
派生的
的构造函数是私有的,所以这个类的使用会很棘手,但我认为这不是问题所在。为什么不尝试使用更简单的访问方式呢?例如,一个只返回
x
(提示:您不需要指定
base::
来访问它)的派生类函数是否回答了您的问题?这很相似。为什么不只用:g=&x@SebastianRedl您链接的问题是关于在另一个实例上调用受保护的方法,事实并非如此here@user463035818但道理是一样的。您试图通过非您的类的访问路径访问受保护的成员。这就是为什么宋元耀的答案是有效的。这是有效的,因为你是从base内部访问base::x的,它显然有访问权限。@ChrisUzdavinis我没有删除任何行,给出问题中错误的行仍然存在,并且愉快地编译,没有错误。我刚刚通过添加构造函数修复了其他错误。@user463035818
g=&x?否。
&x
的类型为
int*
,无法将其分配给指向成员的指针。这是因为派生类只允许访问其自身类型的基本受保护成员。想象一个具有受保护成员的形状基类。如果Square继承了它,我们就不希望Square访问圆的受保护成员。(重点是,仅仅因为X从基继承并不意味着X应该可以访问所有受基保护的成员,只能访问类型为X的对象实际使用的那些成员。)基::限定不再位于派生类的上下文中,因此受保护的访问阻止了它
&foo::x
我不知道(第一个是
int*
,第二个是指向
int
成员的指针)@user463035818是的。对于这种情况,
&(派生的::x)
&(x)
&x
@ChrisUzdavinis相同,我已经思考了一段时间,为什么派生类成员或朋友只能通过派生对象访问基类的受保护成员。我不同意你的例子。我认为关键是,在类中设置
protected
,意味着用户不能从类本身之外的任何地方访问它,即使是从派生类。检查这个
base() : g(&base::x) {}