Может ли переменная вызывать частную функцию?
Скажем, вам дана следующая диаграмма классов 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
можно назвать private
s. Например:
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;
}
Как говорится, не делай этого. Частные методы являются частными по определенной причине - они воплощают скрытые аспекты дизайна и никогда не предназначались для того, чтобы быть частью открытого интерфейса. Это означает, что они могут быть подвержены изменению поведения или даже полному удалению. Кроме того, выполнение такого рода махинаций может привести к тому, что код будет сильно и неловко связан, что нежелательно.
Это, как говорится, я действительно использовал это, и это работает довольно хорошо, хотя это было в совершенно другом контексте, где это помогло уменьшить сцепление (это было в высокомодульной схеме регистрации событий, если вам интересно).
Любой метод внутри класса может получить доступ к закрытым переменным и методам. Он работает точно так же, как и при вызове любого другого метода, просто компилятор выдаст вам ошибку, если вы попытаетесь сделать это извне класса.