2015-02-17 2 views
2

Возможно, странно, что я пытаюсь увидеть, и я попытаюсь как можно больше разъяснить. Я использую gcc 4.8 на ubuntu 14.04 и C++ 11.метод дочернего класса метод указатель метода родительский аргумент C++

Что я хочу пытаться сделать это:

  • сделать класса А
  • сделать функцию в этом классе А, которая получает в качестве аргумента
  • указатель на класс члена того же класса
  • сделать новый класс B, который наследует от
  • сделать новый метод класса B
  • дает указатель на этот метод класса В к способу ParentClass А в качестве аргумента

    class A{ 
        typedef void(A::*METHOD);   
    
        void executeMethod(METHOD arg){}; 
    } 
    
    class B : A{ 
    
        void sampleMethod(){}; 
    
        void childMethod(){    
    
         this->executeMethod(&B::sampleMethod); //<== error 
        } 
    } 
    

Однако это приносит мне следующее сообщение об ошибке в CodeBlocks:

error: no matching function to call for 'B::executeMethod(void B::*)' 

Есть ли способ обойти это? Есть ли что-нибудь еще, что мне нужно сделать, чтобы дать вам понять, чего я пытаюсь достичь?

ответ

0

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

class A { 
public: 
    template<class T> 
    void executeMethod(void (T::*method)()) 
    { 
     (static_cast<T *>(this)->*method)(); 
    } 
}; 

class B : public A { 
public: 
    void sampleMethod() {} 
    void childMethod() { executeMethod(&B::sampleMethod); } 
}; 

Но более гибкое решение было бы использовать std::function и std::bind как тогда вы можете передать методы, которые подпись не совпадает ,

class A { 
public: 
    typedef std::function<void()> Method; 

    void executeMethod(const Method &method) 
    { 
     method(); 
    } 
}; 

class B : public A { 
public: 
    void sampleMethod1() {} 
    void sampleMethod2(int param) {} 

    void childMethod1() { executeMethod(std::bind(&B::sampleMethod1, this); } 
    void childMethod2() { executeMethod(std::bind(&B::sampleMethod2, this, 123); } 
}; 
+0

typedef std :: function Метод; дает мне ошибку: 'function' не называет тип – philsegeler

+0

@philsegeler вам нужно включить '' – Slava

2

Проблема заключается в том, что sampleMethod не является членом A, он является членом B и не может преобразовать в void(A::*).

Возможно, вы считали использование виртуальных методов?

2
typedef void(A::*METHOD);   

определяет METHOD как указатель типа void* переменного члена A, не является указателем на функцию члена A.

Понадобится:

typedef void (A::*METHOD)();   

Даже с этим изменением, вы не можете использовать функцию-член B передать в качестве аргумента, где METHOD ожидается.

Вы можете сделать функцию, которую хотите передать виртуальной функции-члену A и использовать ее.

class A { 
    protected: 
     typedef void(A::*METHOD)();   

     void executeMethod(METHOD arg){}; 

    public: 
     virtual void sampleMethod() = 0; 
}; 

class B : public A { 

    virtual void sampleMethod(){}; 

    void childMethod(){    

     this->executeMethod(&A::sampleMethod); 
    } 
}; 
1

Чтобы сделать вызываемый объект привязанным к функции-члену, вы должны использовать std :: bind. Это создаст переадресацию, которая вызовет метод sampleMethod с некоторыми из его предварительно заданных параметров. В этом случае параметр «this» будет связан.

std :: bind (& B :: sampleMethod, this);

+0

Прежде всего, OP не нуждается в указателе функции, он запрашивает указатель на метод. Второй 'std :: bind()' не будет вызывать указатель на функцию. – Slava

+0

Согласовано. Моя терминология была очень свободной. Я отредактирую, чтобы исправить формулировку. –

Смежные вопросы