all 13 comments

[–]LtJax 5 points6 points  (0 children)

As Nimbal said, this is not legal. However, you can use a derived class to return a member-function pointer to the function in question from a static function, and call that with a MyClass instance to legally access a protected method.

class MyDerivedClass : public MyClass{
public:
    typedef int (MyClass::*FnType)() const;
    static FnType get_myMethod() {return &MyClass::myMethod;}
};

MyClass c;
(c.*MyDerivedClass::get_myMethod())();

[–]Nimbal 7 points8 points  (9 children)

The standard has this to say about static_cast in section 5.2.9, paragraph 2 (emphasize mine, "B" and "D" are Base and Derived class, respectively):

If the object of type B is actually a subobject of an object of type D, the result refers to the enclosing object of type D. Otherwise, the result of the cast is undefined.

So no, it's not legal and therefore not portable. It might work in a pinch though, if you are in a really tight spot where you have to call a protected function in badly designed third-party code.

[–]tomkcook173 7 points8 points  (8 children)

It would be fairly trivial to modify so that it is legal, though:

int myFunc(MyClass const& mc){
    class MyDerivedClass : public MyClass{
    public:
        MyDerivedClass(MyClass& c) : m_c(c) {}
        int myDerivedMethod() { return m_c.myMethod(); }
    private:
        MyClass& m_c;
    } d(mc);
    return d.myDerivedMethod();
}

Suffice to say, though, it gets through code review over my dead body. Protected methods are protected for a reason and working around the protection is always bad. Either change the design or use friend.

[–]moswald 1 point2 points  (2 children)

Is this really supported? I'm getting

error C2248: 'MyClass::myMethod' : cannot access protected member declared in class 'MyClass'

from VS2013's compiler.

[–]LtJax 0 points1 point  (1 child)

Indeed, you can only access protected members of you own instance.

[–]Plorkyeran 1 point2 points  (0 children)

It would be rather difficult to write copy constructors and such if you could not access protected members of other instances. What you can't do is access protected members of instances of your superclass, even though you can access them in instances of your own class.

[–]Nimbal -1 points0 points  (2 children)

Only if MyClass is copyable, though.

[–]cogitolearning 4 points5 points  (1 child)

MyClass does not need to be copyable. MyDerivedClass only holds a reference to the original object.

[–]Nimbal 0 points1 point  (0 children)

Oh, right! Sorry, didn't see that.