Can a variable call a Private function?

1.4k views Asked by At

Say you are given the following UML class diagram:

Mystery UML Class Diagram

Can a variable of type Mystery invoke the function DoSomething()?

I understand that an object (say Mystery X;) could call GetA() to access the private variable int a and to access the public variable int b all you need is X.b but how could this object, X, access the private function DoSomething() if it's even possible?

3

There are 3 answers

2
John Dibling On BEST ANSWER

I had difficulty understanding exactly what you are asking, but I think I've figured it out.

If you are asking if, given the following declaration:

class Mystery
{
/*...*/
private:
  void DoSomething();
};

you can do something like this:

Mystery m;
m.DoSomething();

...then the answer is no. You cannot call private member functions (or refer to private member variables) from outside the context of the class. Only another member function of Mystery can call the privates. For example:

void Mystery::Foo()
{
  DoSomething();  // this would be possible if Foo() is a member of Mystery
}

EDIT:

Not only can you not call private members from outside the class, you also can't call them from subclasses. For example, this is not valid:

class Base
{
private:
    void Foo() {};
};

class Child : public Base
{
public:
    void Bar() 
    { 
        Foo();  // ERROR:  Can't call private method of base class
    }
};
3
Winston Ewert On

Any method inside the class is allowed to access the private variables and methods. It works exactly like calling any other method, its just that the compiler will give you an error if you try to do it from outside the class.

5
Nate On

There is one (edit - for completeness sake, there is more than one, see the comments) weird way that a private member function could be called outside your class, but it requires a little bit of a contrived example, where you can return a pointer to this function:

class Mystery;
typedef void (Mystery::*fptr)();

class Mystery{
    void DoSomething() {};
public:
    static fptr GetPrivateDoSomething()
    {
        return &DoSomething;
    }
};

int main(int argc, char *argv[])
{
    Mystery m;
    fptr ds = Mystery::GetPrivateDoSomething();
    (m.*ds)();
    return 0;
}

That being said, don't do this. Private methods are private for a reason - they embody hidden aspects of the design, and were never meant to be a part of the exposed interface. That means that they could be subject to a change in behavior, or even complete removal. Additionally, doing these sorts of shenanigans can lead to code that is highly and awkwardly coupled, which is undesirable.

THAT being said, I have indeed used this and it works quite well, although it was in an entirely different context where it helped to reduce coupling (it was in a highly-modular event registration scheme, if you were wondering).