Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't access protected member in base class from derived class

Heres my code :

#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)
{
}

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?

like image 781
Brian Brown Avatar asked May 09 '13 10:05

Brian Brown


People also ask

Can base class access protected members of derived class?

Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.

Can derived class access protected members of base class in Java?

A class can only access protected members of instances of this class or a derived class. It cannot access protected members of instances of a parent class or cousin class. In your case, the Derived class can only access the b protected member of Derived instances, not that of Base instances.

Which type of members can't be accessed in derived classes of a base class protected Public Private All can be accessed?

Which type of members can't be accessed in derived classes of a base class? Explanation: The private members can be accessed only inside the base class. If the class is derived by other classes. Those members will not be accessible.

Can derived classes be access protected?

A derived class cannot access protected members of its base class through an instance of the base class. An instance of the base class declared in the derived class might, at run time, be an instance of another type that is derived from the same base but is not otherwise related to the derived class.


1 Answers

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

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;
}

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

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)
}

— end example ]

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++)
//              ^^^^^^

You could write this:

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

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);

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).

like image 139
Andy Prowl Avatar answered Sep 30 '22 04:09

Andy Prowl