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?
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.
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? 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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With