статический метод с полиморфизмом в с ++ - PullRequest
3 голосов
/ 09 октября 2009

У меня странная проблема с использованием полиморфизма. У меня есть базовый класс, который реализует статический метод. Этот метод должен быть статическим по разным причинам. Базовый класс также имеет чисто виртуальный метод run(), который реализуется всеми расширенными классами. Мне нужно иметь возможность звонить run() из статического класса.

Проблема, конечно, в том, что статический класс не имеет указателя this. Этот метод может быть передан в параметре void *. Я пытался придумать умный способ передать в него метод run, но пока ничего не получалось. также пытался передать это в него. Проблема с этим заключается в том, что мне пришлось бы создать его экземпляр, что требует знания расширенного класса. Это побеждает всю цель полиморфизма.

Есть идеи, как это сделать?

Ответы [ 4 ]

9 голосов
/ 09 октября 2009

Не передавайте его как пустой указатель *, передавайте его как указатель (или ссылку) в базовый класс:

class BaseClass
{
public:
  static void something(BaseClass* self) { self->foo(); }
  virtual void foo() = 0;  
};
5 голосов
/ 09 октября 2009

Обычно это происходит, когда вам приходится сжимать объекты C ++ через C API. Классическим примером является класс потока.

Вот стандартная идиома для этого:

/** calls thread_func in a new thread passing it user_data as argument */
thrd_hdl_t c_api_thread_start(int (*thread_func)(void*), void* user_data);

/** abstract thread base class
* override my_thread::run to do work in another thread
*/
class my_thread {
  public:
    my_thread() hdl_(c_api_thread_start(my_thread::thread_runner,this)) {}
    // ...

  private:
    virtual int run() = 0; // we don't want this to be called from others

    thrd_hdl_t hdl_; // whatever the C threading API uses as a thread handle

    static int thread_runner(void* user_data)
    {
      my_thread* that = static_cast<my_thread*>(user_data);
      try {
        return that->run();
      } catch(...) {
        return oh_my_an_unknown_error;
      }
    }
};

Это поможет?

3 голосов
/ 09 октября 2009

Почему бы не передать ссылку на объект, а не на метод, например,

static void func( BaseObject& o)
{
     o.run();
}
1 голос
/ 09 октября 2009

IMO, ваш лучший выбор - избавиться от статического метода. Найдите способ обойти , , и вы золотые.

...