Могу ли я получить доступ к базовым классам защищенных членов из статической функции в производном классе? - PullRequest
19 голосов
/ 05 сентября 2011

У меня есть программа, в которой мне нужно создать базовый класс, который разделяется между 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 общедоступными, но это было бы плохо, поскольку в моем реальном случае это кусок выделенной памяти и семафоры для защиты ее от многопоточности.

Справка?

Ответы [ 2 ]

13 голосов
/ 05 сентября 2011

В целом (независимо от того, является ли функция статической или нет), функция-член производного класса может получить доступ только к защищенной базе члены класса объектов своего типа. Он не может получить доступ к защищенным члены базы, если статический тип не является типом производного класса (или класс, производный от него). Итак:

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...
    }
} ;
0 голосов
/ 05 сентября 2011

Спецификатор доступа применяется к дескриптору класса 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;
...