Используйте std::bind для привязки к родительской версии виртуальной функции.

Я хочу создать объект std::function для версии родительского класса виртуальной и переопределенной функции, см. следующий пример:

#include <iostream>
#include <functional>

class Parent
{
    public:

        virtual void func1()
        {
            std::cout << "Parent::func1\n";
        }

        virtual void func2()
        {
            std::cout << "Parent::func2\n";
        }
};

class Child : public Parent
{
    public:

        // overrides Parent::func1
        virtual void func1()
        {
            std::cout << "Child::func1, ";
            Parent::func1();
        }

        // overrides Parent::func2
        virtual void func2()
        {
            std::cout << "Child::func2, ";
            std::function< void() > parent_func2 = std::bind( &Parent::func2, this );
            parent_func2();
        }
};

int main()
{
    Child child;

    child.func1(); // output: Child::func1, Parent::func1

    child.func2(); // output: Child::func2, Child::func2, ...

    return 0;
}

В то время как вызов child.func1() ведет себя так, как ожидалось, вызов child.func2() становится бесконечной рекурсией, где parent_func2() кажется вызывает Child::func2() вместо Parent::func2(), к которому я намеревался его привязать.

Есть идеи, как заставить parent_func2() действительно позвонить Parent::func2?


person Sebastian Schneider    schedule 08.10.2013    source источник
comment
Я не думаю, что вы можете сделать это напрямую, это все равно будет выполнять только виртуальную отправку. Лучшей идеей будет лямбда вроде [=]{ this->Parent::func2(); }.   -  person Xeo    schedule 08.10.2013
comment
Почему Parent::func2 отправляется в Child::func2 при вызове std::bind, а Parent::func1 — нет? Даже если ваш обходной путь может сработать, я хотел бы понять, почему это так.   -  person Sebastian Schneider    schedule 08.10.2013
comment
Поскольку виртуальная диспетчеризация все еще выполняется, насколько мне известно, она отключается только явным вызовом родительской функции.   -  person Xeo    schedule 08.10.2013


Ответы (1)


Вы можете сделать это, написав небольшой функтор:

struct Parent_func2
{
  void operator()( Parent* p ) const
  {
    p->Parent::func2();
  }
};

И использовать

std::function< void() > parent_func2 = std::bind( Parent_func2(), this );

(думая об этом, я думаю, что это просто более подробный способ того, что предложил Xeo. @Xeo, сделайте свой комментарий ответом, и вы получите мой голос...)

person Daniel Frey    schedule 08.10.2013