Могу ли я получить доступ к элементам, защищенным базовыми классами, от статической функции в производном классе?
У меня есть программа, в которой мне нужно создать базовый класс, который используется совместно с dll и некоторым кодом приложения. Тогда у меня есть два разных производных класса: один в dll в основном приложении. Каждый из них имеет некоторые статические функции-члены, которые работают с данными в классе nase. (Они должны быть статическими, поскольку они используются в качестве указателей на функции в другом месте). В самой простой форме моя проблема показана ниже.
class Base {
protected:
int var ;
};
class Derived : public Base {
static bool Process( Base *pBase ) {
pBase->var = 2;
return true;
}
};
Мой компилятор жалуется, что я не могу получить доступ к защищенным членам pBase, хотя Derived защитил доступ к Base. Есть ли способ обойти это или я что-то не понимаю?
Я могу сделать базовые переменные общедоступными, но это было бы плохо, поскольку в моем реальном примере это кусок выделенной памяти и семафоров, чтобы защитить ее для многопоточности.
Справка
Ответы
Ответ 1
В целом (независимо от того, является ли эта функция статической или нет),
функция-член производного класса может получить доступ только к защищенной базе
членов класса объектов его типа. Он не может получить доступ к защищенным
члены базы, если статический тип не относится к производному классу
(или производный от него класс). Итак:
class Base {
protected:
int var;
} ;
class Derived : public Base {
static void f1( Derived* pDerived )
{
pDerived->var = 2; // legal, access through Derived...
}
static bool Process( Base *pBase )
{
pBase->var = 2 ; // illegal, access not through Derived...
}
} ;
Ответ 2
Спецификатор доступа применяется к дескриптору класса Derived
(reference/pointer/object), а не к методам самого класса Derived
. Даже если метод не был static
, вы попали бы в ту же ошибку. Потому что вы не получаете доступ к var
с помощью производного дескриптора. Демо.
Правильный способ - предоставить метод setter
:
class Base {
protected:
int var ;
public:
void setVar(const int v) { var = v; } // <--- add this method
};
Примечание. Есть еще один выход, но я не уверен, что он изящный.
(static_cast<Derived*>(pBase))->var = 2;