Могу ли я получить доступ к базовым классам, защищенным членами, от статической функции в производном классе?
-
26-10-2019 - |
Вопрос
У меня есть программа, в которой мне нужно сделать базовый класс, который разделяется между DLL и некоторым кодом приложения. Тогда у меня есть два разных полученных класса, один в DLL в основном приложении. Каждый из них имеет некоторые статические функции, которые работают на данных в классе NASE. (Они должны быть статичными, как они используются в качестве указателей функций в других местах). В самой простой форме моя проблема показана ниже.
class Base {
protected:
int var ;
};
class Derived : public Base {
static bool Process( Base *pBase ) {
pBase->var = 2;
return true;
}
};
Мой компилятор жалуется на то, что я не могу получить доступ к защищенным членам PBASE, даже если Defived защитил доступ к базе. Есть ли способ обойти это или я что -то неправильно понимаю? Я могу сделать базовые переменные публичными, но это было бы плохо, так как в моем реальном случае это кусок выделенной памяти и семафоры, чтобы защитить ее для многопоточного чтения.
Помощь?
Решение
В целом (независимо от того, является ли функция статической или нет), функция элемента полученного класса может получить доступ только к защищенному базовому классу объектов его типа. Он не может получить доступ к защищенным членам базы, если статический тип не является результатом полученного класса (или полученного из него класса). Так:
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...
}
} ;
Другие советы
Спецификатор доступа применяется к Derived
ручка класса (ссылка/указатель/объект), а не методы 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;