Могу ли я получить доступ к базовым классам, защищенным членами, от статической функции в производном классе?

StackOverflow https://stackoverflow.com/questions/7307200

Вопрос

У меня есть программа, в которой мне нужно сделать базовый класс, который разделяется между 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top