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