Как обеспечить, чтобы во время выполнения функция-член в унаследованном классе была закрытой?(C ++, GCC) - PullRequest
0 голосов
/ 13 сентября 2011

A - базовый класс, B - унаследованный класс. A получает указатели на функции-члены от B , связанные с boost :: bind + boost :: function, для последующего хранения и выполнения из других функций базового класса.Классы A и B находятся в отдельных включаемых файлах.Я хотел бы ограничить разработчика, который реализует унаследованные классы от A , чтобы указатели связанных функций-членов в унаследованных классах были частными функциями.Средой является C ++, gcc 4.x и Linux.

Пример:

------ INCLUDE FILE -----

#include <boost/bind.hpp>
#include <boost/function.hpp>

struct A
{
protected:
    void Register(const char* name, boost::function<void()> FuncPtr)
    {
      // (I am not intended to pass the name argument, but probably somebody
      // knows something gcc magic which would use it to solve the problem.)
      // I want to ensure that FuncPtr points to a private member
      // function. What can be known: "B::CalledFunction" string and FuncPtr.
      // If it is not a private member function then drop an error message
      // during run-time or during compilation (???).
    }
};

------ OTHER INCLUDE FILE -----
...

struct B : public A
{
    B() : A()
    {
      Register("B::CalledFunction", boost::bind(&B::CalledFunction, this));
    }

private:
    void CalledFunction()
    {
    }
};

Любой вид магии магии или подобные вещи также могут быть оценены до / вместо простого прямого вызоваA::Register().

Ответы [ 2 ]

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

К сожалению, запрашиваемое вами ограничение невозможно. Ограничения доступа присутствуют только во время компиляции, а не во время выполнения; единственное, что они делают, это контролируют (на основе лексическая область действия), на какие идентификаторы можно ссылаться.

Поскольку вызывающий контекст, производящий эти связанные функции-члены, очевидно, имеет доступ ко всем его функциям-членам, вы не можете различить приватные и публичные функции-члены локально - это исключает любые макро-взломы. Кроме того, указатели на функции-члены не сохраняют информацию об управлении доступом (поэтому вы можете вызывать указатель на приватную функцию-член из другого класса). Таким образом, проверка в другом месте также невозможна.

Вы можете реализовать это как передачу компилятором чего-то вроде clang , так как информация доступна там во время компиляции; однако это невозможно с обычным компилятором C ++. Однако это может быть склонно к ложным срабатываниям и ложным отрицаниям, так как ситуация, в которой это проблема, является несколько плохо определенной (что если некоторый производный класс B действительно хочет связанную публичную функцию-член, что он будет использовать в другом месте?)

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

Вместо того, чтобы расширять комментарии, я предложу альтернативу, основанную на использовании наследования

#include <iostream>
#include <memory>

class A
{
  public:
    void call_a() { some_func_a(); }
  private:
    virtual void some_func_a() = 0; // pure virtual
};

class B : public A
{
  private:
    void some_func_a() { std::cout << "B::some_func_a" << std::endl; }
};

int main(void)
{
  std::auto_ptr<A> a(new B);
//  a->some_func_a();  // causes compiler error
  a->call_a();
}

Если вы пропустите определение some_func_a в B, вы получите ошибку компилятора при попытке создать экземпляр B.

...