1

I've written the following code:

#include <stdio.h>

class A
{
protected:
    void foo()
    {
        printf("class A\n");
    }
};

class B : public A
{
    void bar()
    {
        printf("class B\n");
    }
};

int main()
{
    B *b= new B();
    b->foo();
}

And when I'm compiling it I've an error

test.cpp: In function ‘int main()’:
test.cpp:6:7: error: ‘void A::foo()’ is protected
test.cpp:23:9: error: within this context

But in the N3797 working draft said that

protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends

and

if a class is declared to be a base class (Clause 10) for another class using the public access specifier, the public members of the base class are accessible as public members of the derived class and protected members of the base class are accessible as protected members of the derived class.

  • 1
    http://stackoverflow.com/questions/967352/why-cant-i-access-a-protected-member-from-an-instance-of-a-derived-class?rq=1 – Pavel May 09 '14 at 12:26
  • 4
    I don't understand the question. `main` is neither a member of `B`, nor a friend of it, so why would it get access to any non-public member of it? –  May 09 '14 at 12:27

4 Answers4

4

Your code, which tries to call b->foo(), is:

  • not a member of A
  • not a friend of A
  • not a member of B (the only derived type)
  • not a friend of B

so by the passage you quote, it cannot use the name foo.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

To put it simply: You are trying to access the protected member from outside your class hierarchy. The following would work:

class B : public A
{
    void bar() // bar is "inside" your class hierarchy
    {
        foo(); // compiles
        printf("class B\n");
    }
};

But this not:

// some code, e.g. in main
b->foo(); // error - "outside" of the class

See Jon's answer for a formal explanation.


Note: Your class B could make the protected member public, like this:

class B : public A
{
public:
    // This adds a public foo to B, which invokes the protected foo from A
    void foo()
    {
        A::foo(); 
    }
};

With that, your example would work, as long as you're using a B pointer/instance/reference.

Community
  • 1
  • 1
lethal-guitar
  • 4,438
  • 1
  • 20
  • 40
0

B, not main, can access A's members.

Options:

  1. Make foo() public, instead of protected
  2. Have a public method within B that calls foo() and call that.
Islay
  • 478
  • 4
  • 17
0

From main you can just access public members of B defined in B or inherited from A.

k-messaoudi
  • 347
  • 2
  • 5