Unable to access protected member in base class from derived class

Here is 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 array in a derived class, I just can't, 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 everything seems to be fine, but it is not. How to fix it?

+6
source share
1 answer

I read that protected members are private in derived classes, so it seems like this is normal, but it is not.

This is not because the protected item inherited from the base class A ( root , in this case) by the derived class B ( aa , in this case) is available for how long since it accesses an object of type B ( aa ). Here you access 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; } 

In paragraph 11.4 / 1 of the C ++ 11 standard:

The extra access control beyond the limits described in section 11 above applies when the non-static data member or non-static member function is a protected member of its naming class (11.2). As previously described, access to a protected member is granted because the link is found in a friend or member of a class C. If access consists in forming a pointer to a member (5.3.1), the naming specifier should denote C or a class derived from C. All other calls include an (possibly implicit) expression of the object (5.2.5). In this case, the class of the expression of the object must 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 of example]

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

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

You can write this:

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

Similarly, you will need to provide functions to get / set the value of the nth element of the array so you can write:

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

Note that the expression on the left is += OK, because array accessed through this (see also the example above from the C ++ 11 standard).

+6
source

Source: https://habr.com/ru/post/944620/


All Articles