Accessing Protected Members in a Derived Class

Accessing protected members in a derived class

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.

Changing the constructor to take a Derived instance will solve the problem.

Can we access protected member functions of base class in derived class?

Yes, the derived class can access protected members, whether those members are data or functions. But in your code, it's main which is attempting to access setWidth and setHeight, not Rectangle. That's invalid just like using width and height from main would be.

An example of the derived class using the protected member functions:

class Rectangle: public Shape {
public:
int getArea() const {
return (width * height);
}
void setDimensions(int w, int h) {
setWidth(w);
setHeight(h);
}
};

Or if you really want Rectangle to let anyone else use the functions, you can use the access Rectangle has to make them public members of Rectangle instead of protected:

class Rectangle: public Shape {
public:
using Shape::setWidth;
using Shape::setHeight;

int getArea() const {
return (width * height);
}
};

Derived class cannot access the protected member of the base class

The derived class could access the protected members of base class only through the context of the derived class. On the other word, the derived class can't access protected members through the base class.

When a pointer to a protected member is formed, it must use a derived
class in its declaration:

struct Base {
protected:
int i;
};

struct Derived : Base {
void f()
{
// int Base::* ptr = &Base::i; // error: must name using Derived
int Base::* ptr = &Derived::i; // okay
}
};

You can change

g = &base::x;

to

g = &derived::x;

How can I access base class's protected members through derived class?

There is not more to it than you already discovered. Derived instances may acces their protected members and those of other derived instances but not those of base class instances. Why? Because thats how protected works by definition.

For more details I refer you to cppreference (emphasize mine):

A protected member of a class Base can only be accessed

1) by the members and friends of Base

2) by the members and friends (until
C++17) of any class derived from Base, but only when operating on an
object of a type that is derived from Base (including this)

Accessing protected members in derived class C++

Just based on the code you provided, it doesn't appear you allocated any memory to the char * member variables in order to store a string. If my assumption is correct, then your program is failing because it is trying to copy a string into a pointer that is not pointing to any valid memory space, which causes undefined behavior. I am going to give you the minimal, best, safest edits that you can make that would solve your problem.

class Patient
{
public:
Patient();
virtual void parse();
virtual void toString();
virtual void enterPatientData();

protected:
std::string name;
std::string SSN;
std::string insuranceName;
std::string insuranceNumber;
std::string age;
std::string spouseName;
std::string diagnosis;

};

Change the type of each protected member variable from a char * to a std::string will now allow you to read in strings from the standard input and store them within each member variable, and the std::string object will handle all necessary memory allocation as needed (as well as cleaning it up when it is no longer being used). You should then be able to use your function FemaleIn::enterPatientData as is because the syntax is correct.

Other than that, as others have pointed out, you may want to reconsider your class hierarchy design, but that should not be a problem here. You also may want to reconsider how you store some types of variables (e.g., age might be better stored as an int).

C++ - Accessing protected/private members of a base class

To my understanding, in public inheritance, protected members of the base class become protected members of the derived class and should be able to e accessed like public members. Is that incorrect?

This is mostly true. Public and protected members of base classes are accessible in derived classes (public inheritance doesn't matter here - that only affects outside observers' access). However, class members (of any access) can only be initialized in their own class. In this case, only Shape can initialize length and width - it doesn't matter that they're protected, the same would be true if they were public or private.

You would have to add a constructor to do this, which your Rectangle constructor could simply delegate to. This works regardless of the access control of length and width (as long as the Shape constructor is public or protected):

struct Shape {
Shape(int l, int w) : length(l), width(w) { }
};

struct Rectangle {
Rectangle(int l, int w) : Shape(l, w) { }
};

Or, for completeness, you could just assign them, but definitely prefer to have Shape initialize them. Additionally, this only works if the members in question are public or protected:

Rectangle(int l, int w) {
length = l;
width = w;
}

Note that your setWidth() and setLength() functions are fine - you do have access to those protected members in Rectangle's member functions. Just not for initialization.

Casting an object to a derived class to access protected members of parent class

What you do is UB.

There is one magical way to access private/protected member in C++:

The ISO C++ standard specifies that there is no access check in case of explicit template instantiations, and following code abuse of that:

template <typename Tag>
struct result
{
using type = typename Tag::type;
static type ptr;
};

template <typename Tag> typename result<Tag>::type result<Tag>::ptr;

template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};

template <typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;

And then

struct NodeVal { using type = int Node::*; };
template class rob<NodeVal, &Node::val_>;

and finally:

int main() {
Node node = /**/;
(node.*result<NodeVal>::ptr);
}

Demo

java - protected members accessed in derived class using base class instance

You're right that you can't do this. The reason why you can't access the field, is that you're not in the same package as the class, nor are you accessing an inherited member of the same class.

The last point is the critical one - if you'd written

MyCollection2 mc = new MyCollection2();
mc.intg = 1;

then this would work, as you're changing a protected member of your own class (which is present in that class through inheritance). However, in your case you're trying to change a protected member of a different class in a different package. Thus it should come as no surprise that you're denied access.

Access protected members of base class in grandchild class

Your problem is that you're inheriting from you base classes privately, so public and protected members of the base class get the same access control as private members of the derived class. While possible, private inheritance is a very specific tool and used rarely. In the vast majority of cases, you want public inheritance:

class SmallBox: public Box {
protected:
double height;
};

class TooSmall: public SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};

Done this way, protected members will be visible to all descendants (not just direct children) normally.


If, for some reason, you want to stick with private inheritance, you will have to "promote" the privately-inherited protected members back to protected:

class SmallBox:Box {
protected:
double height;
using Box::width; // make it protected again
};

class TooSmall:SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};


Related Topics



Leave a reply



Submit