6

The following code gives an compilation error for void b() { m = &A::a; }; stating that A::a() is protected. (Which it is - but that should be no problem)
However the compiler doesn't care when I write B::a(). Even though both mean the same I would prefer A::a() because it states explicitely that a() is defined in A.

So what is the reason why A::a() is forbidden?
EDIT
Maybe someone can find an example that would be problematic if A::a() was allowed in B::b(). If there is such an example, I will mark it as answer to the question.
/EDIT

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdio>

class A {
protected:
  void a(){ std::cout << "A::a()" << std::endl; };
};

typedef void (A::*f)();
class B : public A {
public:
  void b() { m = &A::a; }; // wont compile
  // void b() { m = &B::a; }; // works fine
  void c() { (this->*m)(); };
protected:
  f m;
};

int main(){
  B b;
  b.b();
  b.c();
}

// compile with
// g++ -Wall main.cpp -o main

Explanation of the code:
In B I want to store a function pointer to a method in A to be able to call that later in B::c(). And yes, this happens in real life too. :-)

2
  • Amusing... happens both with gcc-3.4.2 and gcc-4.3.2 Commented Feb 22, 2010 at 12:56
  • may be related to stackoverflow.com/questions/477829/… Commented Feb 22, 2010 at 13:09

3 Answers 3

2

Because otherwise the outside world can find this protected member: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11174.

See also http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00610.html.

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm, in my ignorance I still can't see why it is necessary. The function-pointer and thus the method is still protected in B. So it is not accessible from outside and if it was so would B::b() or am I missing the point completely?
@tuner07, access protection is determined by the static type of the expression. The actual context in which you take the function-pointer doesn't come into play.
@gf If the access protection is determined by the static type of the expression it shouldn't be possible to call A::a() anywhere in B. But that is possible. So the rule applies only to the case where a function is stored into a function-pointer. I can still see no reason why A::a() must be prevented by the compiler.
1

The reason should be similar to why you can't do this in B either:

class B: public A
{
    //...
    void foo(A& x) {
        x.a(); //error
    }

    void foo(B& x) {
        x.a(); //OK
    }
};

That protected doesn't mean that B can access the A part of any class as long it is an A / derived from A. The protected stuff is only available for this and other instances of B.

Comments

0

You try to access protected member through global namespace (A::a is ::A::a here), use B::A::a instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.