Может ли переменная вызывать частную функцию?

Скажем, вам дана следующая диаграмма классов UML:

Диаграмма классов Mystery UML

Может переменная типа Mystery вызвать функцию DoSomething()?

Я понимаю, что объект (скажем, Mystery X;) мог позвонить GetA() получить доступ к закрытой переменной int aи получить доступ к публичной переменной int b все, что тебе нужно X.bно как мог этот объект, X, получить доступ к частной функции DoSomething()если это вообще возможно?

3 ответа

Решение

Мне было трудно понять, что именно вы спрашиваете, но, думаю, я понял это.

Если вы спрашиваете, если дано следующее объявление:

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

Вы можете сделать что-то вроде этого:

Mystery m;
m.DoSomething();

... тогда ответ - нет. Вы не можете позвонить private функции-члены (или обратитесь к private переменные-члены) вне контекста класса. Только другая функция-член Mystery можно назвать privates. Например:

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

РЕДАКТИРОВАТЬ:

Вы не только не можете позвонить private членов из-за пределов класса, вы также не можете вызывать их из подклассов. Например, это недопустимо:

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

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

Существует один (отредактировать - для полноты, их больше одного, см. Комментарии) странный способ вызова закрытой функции-члена вне вашего класса, но для этого требуется немного надуманного примера, в котором вы можете вернуть указатель на эту функцию:

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;
}

Как говорится, не делай этого. Частные методы являются частными по определенной причине - они воплощают скрытые аспекты дизайна и никогда не предназначались для того, чтобы быть частью открытого интерфейса. Это означает, что они могут быть подвержены изменению поведения или даже полному удалению. Кроме того, выполнение такого рода махинаций может привести к тому, что код будет сильно и неловко связан, что нежелательно.

Это, как говорится, я действительно использовал это, и это работает довольно хорошо, хотя это было в совершенно другом контексте, где это помогло уменьшить сцепление (это было в высокомодульной схеме регистрации событий, если вам интересно).

Любой метод внутри класса может получить доступ к закрытым переменным и методам. Он работает точно так же, как и при вызове любого другого метода, просто компилятор выдаст вам ошибку, если вы попытаетесь сделать это извне класса.

Другие вопросы по тегам