Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ simple inheritance problem

#include <iostream>
using namespace std;
class A
{
protected:
    int a;
};
class B : public A
{
public:
    int func(A* p)
    {
        cout << p->a;
    }
};

I really cannot understand why I cant access to 'a' by 'p->a'.

Is there anyway to access p's member 'a' in class B, without changing 'protected' to 'public'?

like image 705
Jaebum Avatar asked Sep 12 '11 15:09

Jaebum


People also ask

What is an example of simple inheritance?

Single Inheritance Example When a class inherits another class, it is known as a single inheritance. In the example given below, Dog class inherits the Animal class, so there is the single inheritance.

What is inheritance problem?

Multiple Inheritance is a feature of an object-oriented concept, where a class can inherit properties of more than one parent class. The problem occurs when there exist methods with the same signature in both the superclasses and subclass.

Does C support single inheritance?

No it doesn't. C is not an Object Oriented language. You can try C++ or Java for inheritance functionality.

What is inheritance in C in simple words?

Inheritance in C++ The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming. Inheritance is a feature or a process in which, new classes are created from the existing classes.


3 Answers

On this topic, the C++03 standard states (emphasis mine):

11.5 Protected member access

1 When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5).

What you are doing here, however, is trying to access through a pointer to the base class, which is illegal. If you change the signature to

int func(B* p) // instead of A*

you will find that it now compiles normally.

This is also the reason why you can access a without trouble from inside class B: the access is made through the implicit pointer this, which is of type B* (the derived class again). If you tried this:

A* parent = static_cast<A*>(this);
int x = parent->a; // Does not compile!

You would find that it won't compile, for the very same reason.

The converse also applies: if you downcast the pointer p to a B* you can access the protected member just fine:

class A
{
public:
    // Added virtual destructor so that the class acquires a vptr,
    // making dynamic_cast possible.
    virtual ~A() {};
protected:
    int a;
};

class B : public A
{
public:
    int func(A* p)
    {
        // Now if we downcast p to B* we can access a just fine
        // Of course if p does not actually point to a B, the
        // program will have undefined behavior
        int x = dynamic_cast<B*>(p)->a;
    }
};
like image 63
Jon Avatar answered Sep 28 '22 16:09

Jon


Using p->a would only let you access public variables of A. Since a is a protected variable, you should use cout << a, since a is inherited in class B.

I think you could use cout << p->a by friending class B.

Or by using a pointer to B instead of a pointer to A, as Jon noted.

like image 26
djeidot Avatar answered Sep 28 '22 16:09

djeidot


Ahh, this is a good question. First, let me start off by saying B is NOT a friend of A, and therefore does not have access to A's privates (or protected's) through an "A" view of the object. Even though we are in the scope of class B, we cannot just go around looking at A's privates (or protected's).

HOWEVER, B does have an a. And it does have access to it, because it is declared a protected member of A. But the only way to see int a inside of a B, is to get it from a B view of an object.

like image 28
Chad La Guardia Avatar answered Sep 28 '22 14:09

Chad La Guardia