4

What are the rules for a subclass accessing protected member objects? I thought I understood them but my code disagrees.

I have a base class, defined as

class Datum {
public:
   Datum(Datum *r, Datum *l) : right(r), left(l) {}

protected:
   Datum *right, *left;
};

I subclass Datum as follows:

class Column: public Datum
{
public:
   Column(Datum *r, Datum *l, string n, int s): Datum(r,l), name(n), size(s) {}

   void cover() {
      right->left = left;
      left->right = right;
   }

protected:
   string name;
   int size;
};

When I compile, using G++ v.4.5.1, I get the error messages pointing to the two lines in cover:

error: Datum* Datum::right is protected
error:  within this context
error: Datum* Datum::left is protected
error:  within this context

Obviously, making the section public causes the errors to go away. Why are they there when the section is protected?

sizzzzlerz
  • 4,277
  • 3
  • 27
  • 35
  • 6
    I'm wondering how you create a `Datum` without a `Datum` since there are no constructors that allow you build a `Datum` without `Datum` objects already created. – wkl Oct 25 '11 at 21:09
  • 1
    I guess the top of your Datum class definition should start by `class Datum {` instead of `class Datum:` , right? – Serge Wautier Oct 25 '11 at 21:11
  • @birryree: You don't need existing objects to create one. You only need pointers. Those pointers may be null. – Serge Wautier Oct 25 '11 at 21:12
  • Yeah, I'm converting from python to C++ and I occasionally forget where I am. Assume all is in c++ syntax. – sizzzzlerz Oct 25 '11 at 21:13
  • @Serge - true, I was just a little confused and was thinking you could just use null pointers, but any real state is only handled in the subclass then. – wkl Oct 25 '11 at 21:14
  • @birryree: `NULL` is a valid value for a pointer of any type. Though, one important thing he must do is to check whether those pointers are NULL before dereferencing them. – jweyrich Oct 25 '11 at 21:14
  • @Serge-appTranslator I'm sure you're right -- it wouldn't have compiled at all as written. I fixed that error above. – Caleb Oct 25 '11 at 21:14
  • Also: http://stackoverflow.com/questions/6986798/subtle-c-inheritance-error-with-protected-fields – wkl Oct 25 '11 at 21:18
  • I'm with @birryree; that is an extremely confusing and hard to use constructor. – Ed S. Oct 25 '11 at 21:23

2 Answers2

4

The problem is Datum::Datum *right is protected. Pointer right is accessible / assignable because the base class is inherited publicly. But the object pointed by right has no access previliges the way you are trying to in the member function Column::cover() because the object pointed by right has no direct relation in the current scope of the derived class.

 void cover() {
      // Not posssible right->left = left;

      // But -
       right = new Datum(); // Assuming the class has default constructor.
 }

Similar is the problem for the Datum::Datum *left too.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
3

Column gets access to right and left when they are members of another Column object, but not when they are members of an arbitrary Datum object.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • I don't understand why this answer, which correctly and succinctly answered the question gets no love while the answer that is four times as long but never really answers the question wins the checkmark. – OldFart Oct 26 '11 at 15:39