4

I have encountered a piece of code with method being exposed via public interface while the implementation is private. I'm not sure what should be the expected behavior. Simplified example:

#include <iostream>

class Interface
{
public:
    virtual ~Interface() {}
    virtual void myIfMethod() = 0;
};

class Derived : public Interface
{
private:
    void myIfMethod(){std::cout << "private method invoked via public interface" << std::endl;}
};

int main()
{
    Interface* myObj = new Derived;
    myObj->myIfMethod();
    delete myObj;
    return 0;
}

This sample compiles and executes without a warning: http://ideone.com/1Ouwk4

Is this a correct and well-defined behavior? And if so, why?

Note, the question isn't about private interface method with public implementation (there are multiple such questions on SO) but the other way around.

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
  • It is not incorrect. It is fairly pointless, client code can always cast to the interface type and make the call. A class is not obliged to make an interface method functional, it can throw a "not implemented" exception. You then would be wise to declare it private to lower the exposure risk. – Hans Passant Jan 19 '16 at 11:34
  • There are many questions about this as well. Access protection is a compile-time check, and you're using the interface of `Interface`, where the function is public. – molbdnilo Jan 19 '16 at 11:34

1 Answers1

2

C++ standard draft

Access to virtual functions [class.access.virt]

1 The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.

2 Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

The function is called through a pointer of type Interface in which the member function is public, so the access is allowed. The access of the derived member function is not known and has no effect. The behaviour is correct and well defined as far as the standard is concerned.

Of course, it might be quite pointless to define the overriding function private since it's accessible through virtual dispatch anyway.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Regarding the last point about being pointless; it *could* be useful to make it so you need to use the interface. So if you constructed the concrete class you couldn't call the methods on it since they would be private. – A.J. Oct 26 '16 at 15:16
  • @user3282085 sure, but that invites the question: Is there any point in preventing the use of the interface directly with a concrete class? Seems like useless pessimization to me. – eerorika Oct 26 '16 at 15:21
  • You're right; probably unnecessary prevention. As somebody could static_cast(&concrete). Thanks! :) – A.J. Oct 26 '16 at 15:30