无法从派生类访问基类中的受保护成员 [英] Can't access protected member in base class from derived class

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

问题描述

这里是我的代码:

#include <iostream>
#include <cmath>
#include <sstream>
using namespace std;

class root
{
    protected :

            int size;
            double *array;

    public :

        virtual ~root() {}
        virtual root* add(const root&) = 0;
        virtual root* sub(const root&) = 0;
        virtual istream& in(istream&, root&) = 0;
        virtual int getSize() const = 0;
        virtual void setSize(int);
};

class aa: public root
{

    public :

        aa();
        aa(int);
        aa(const aa&);
        root* add(const root& a);
        root* sub(const root& a);
        istream& in(istream&, root&){}
        int getSize() const;
        void setSize(int);
};

class bb: public root
{
public:
    bb() { }
    bb(const bb& b) { }
    root* add(const root& a);
    root* sub(const root& a);
    istream& in(istream&, root&){}
    int getSize() const{}
    void setSize(int){}
};

aa::aa()
{
    size = 0;
    array = NULL;
}

aa::aa(int nsize)
{
    size = nsize;
    array = new double[size+1];
    for(int i=0; i<size; i++)
        array[i] = 0;
}

root* aa::add(const root& a)
{
    for (int i=0; i<a.size; i++)
        array[i] += a.array[i];
    return *this;
}

root* aa::sub(const root& a)
{
}

int aa::getSize() const
{
    return size;
}

void aa::setSize(int nsize)
{
    size = nsize;
    array = new double[size+1];
    for(int i=0; i<size; i++)
        array[i] = 0;
}

root* bb::add(const root& a)
{
    return new bb();
}

root* bb::sub(const root& a)
{

}

int main(int argc, char **argv)
{
}

当我想在派生类中访问sizearray时,我只是不能,因为我的编译器说:

When I want to access size or an array in derived class, I just cant because my compiler says:

/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root* aa::add(const root&)’:|
/home/brian/Desktop/Temp/Untitled2.cpp|10|error: ‘int root::size’ is protected|
/home/brian/Desktop/Temp/Untitled2.cpp|66|error: within this context|
/home/brian/Desktop/Temp/Untitled2.cpp|11|error: ‘double* root::array’ is protected|
/home/brian/Desktop/Temp/Untitled2.cpp|67|error: within this context|
/home/brian/Desktop/Temp/Untitled2.cpp|68|error: cannot convert ‘aa’ to ‘root*’ in return|
||=== Build finished: 5 errors, 0 warnings ===|

我读到,受保护的成员在派生类中是私有的,因此似乎还可以,但不是.该如何解决?

I read that protected members are private in derived classes, so it seems to be ok, but it isnt. How to fix this?

推荐答案

我读到,受保护的成员在派生类中是私有的,因此这似乎还可以,但不是.

I read that protected members are private in derived classes, so it seems to be ok, but it isnt.

不是因为可以访问派生类B(在这种情况下为aa)从基类A(在这种情况下为root)继​​承的protected数据成员只要在类型为B (aa)的对象上对其进行访问.在这里,您正在通过A(root)类型的对象访问它:

It is not because a protected data member inherited from a base class A (root, in this case) by a derived class B (aa, in this case) is accessible as long as it is being accessed on an object of type B (aa). Here, you are accessing it through an object of type A (root):

root* aa::add(const root& a)
{
    for (int i=0; i<a.size; i++)
    //              ^^^^^^
    //              Accessing size on an object of type `root`, not `aa`!
        array[i] += a.array[i];
    return *this;
}

根据C ++ 11标准的11.4/1段:

Per paragraph 11.4/1 of the C++11 Standard:

当非静态数据时,将应用除第11章中所述之外的其他访问检查. 成员或非静态成员函数是其命名类(11.2)的受保护成员. 如上所述 较早的时候,授予访问受保护成员的权限是因为引用发生在某些朋友或成员中 C类.如果访问要形成指向成员(5.3.1)的指针,则嵌套名称说明符应表示C或a 所有其他访问都涉及一个(可能是隐式的)对象表达式(5.2.5).在这种情况下, 对象表达式的类应为C或派生自C的类. [示例:

An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2). As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall denote C or a class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C. [Example:

class B {
protected:
    int i;
    static int j;
};
class D1 : public B {
};
class D2 : public B {
    // ...
    void mem(B*,D1*);
};

void D2::mem(B* pb, D1* p1) {
    pb->i = 1; // ill-formed
    p1->i = 2; // ill-formed
    // ...
    i = 3; // OK (access through this)
    B::i = 4; // OK (access through this, qualification ignored)
    j = 5; // OK (because j refers to static member)
    B::j = 6; // OK (because B::j refers to static member)
}

—结束示例]

要解决此问题,您需要提供公共设置器/获取器.您已经有一个getSize()函数,因此无需编写此代码:

To fix this, you need to provide public setters/getters. You already have a getSize() function, so instead of writing this:

for (int i=0; i<a.size; i++)
//              ^^^^^^

您可以这样写:

for (int i=0; i<a.getSize(); i++)
//              ^^^^^^^^^^^

类似地,您将必须提供用于获取/设置array的第n个元素的值的函数,以便您可以编写:

Similarly, you will have to provide functions for getting/setting the value of the n-th element of array, so that you could write:

array[i] += a.get_at(i);

请注意,+=左侧的表达式可以,因为正在通过this访问array(另请参见上述示例,来自C ++ 11标准).

Notice, that the expression on the left side of += is OK, because array is being accessed through this (see also the above example from the C++11 Standard).

这篇关于无法从派生类访问基类中的受保护成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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