передать функцию в класс в качестве параметра C ++ - PullRequest
0 голосов
/ 30 января 2020

здесь есть ошибка (но когда я пытаюсь отправить функцию не // класса, ее работа); например, когда я пытаюсь добавить нормальный void zad1 () {somethin ...} его работы, но когда я пытаюсь добавить функцию из класса его нет:

 //Class that send function//
    class Lekcja1 : public ZadanieW {
    private:
        int numerZad;
    public:
        Lekcja1(int num) {
            this->numerZad = num;
        };
        ~Lekcja1() {};
        void tab();
         virtual void LekcjaChose();
    };
    /*void Zad12() {
        cout << "dupa" << endl;
    }*/
    void Lekcja1::tab() {
        cout << "dupa" << endl;
    };
     void Lekcja1::LekcjaChose() {
        wyborZadania* obj = new wyborZadania(numerZad,tab);//there is a problem
        delete obj;
    }
    //Class that takin function//
    class ZadanieW {
    public:
        virtual void LekcjaChose() = 0;
    };
    class wyborZadania{
    public:
        int _chose;
    public:
        wyborZadania(int num,void (*tab)()) {
            this->_chose = num;
            switch (_chose)
            {
            case 1:
                (*tab)();
                break;
            default:
                break;
            }
        }
        ~wyborZadania() {}
    };

Ответы [ 3 ]

1 голос
/ 30 января 2020

tab - это метод Lekcja1, который отличается от обычной функции, поскольку ему необходим доступ ко всем элементам данных Lekcja1.

. Вы можете сделать Lekcja1::tab статическим. c метод, который скрывает доступ к элементу данных и делает его нормальной функцией:

class Lekcja1 : public ZadanieW {
//...
public:
    static void tab();
//...
};

Или, если вам нужен tab для доступа к элементам данных Lekcja1, тогда конструктор wyborZadania должен возьмите указатель на член Lekcja1 и экземпляр Lekcja1 вместо указателя на функцию:

wyborZadania(int num,void (Lekcja1::*tab)(), Lekcja1& instance) {
    // ...
    (instance.*tab)();
    // ...
}

Если вам нужно, чтобы это было более гибко или принимало разные типы классов, тогда wyborZadania должен принимать std::function, который является богатой оболочкой для функции, которая позволит вам связывать аргументы и данные.

wyborZadania(int num,std::function<void()> tab) {
    // ...
    tab();
    // ...
}

А затем в LekcjaChose() передать лямбду для вызова tab () :

wyborZadania* obj = new wyborZadania(numerZad,[this](){ tab(); };

демо: https://godbolt.org/z/XfwpSJ

0 голосов
/ 30 января 2020

метод non-stati c не может быть отправлен в качестве аргумента без указания объекта класса.

Ниже код использует std :: function () для получения этого в простом коде.

#include <iostream>
using namespace std;
#include <functional>

//class wyborZadania;

//Class that takin function//
class ZadanieW {
public:
    virtual void LekcjaChose() = 0;
};

//Class that send function//
class Lekcja1 : public ZadanieW {
private:
    int numerZad;
public:
    Lekcja1(int num) {
        this->numerZad = num;
    };
    ~Lekcja1() {};
    void tab();
    virtual void LekcjaChose();
};
void Zad12() {
cout << "dupa" << endl;
}

class wyborZadania {
public:
    int _chose;
private:
    wyborZadania() {};
public:
    wyborZadania(int num, std::function<void()> tab) {
        this->_chose = num;
        switch (_chose)
        {
        case 1:
            tab();
            break;
        default:
            break;
        }
    }
    ~wyborZadania() {}
};

void Lekcja1::tab() {
    cout << "dupa1" << endl;
};
void Lekcja1::LekcjaChose() {
    wyborZadania* obj = new wyborZadania(numerZad, std::bind(&Lekcja1::tab, this));//there is a problem
    //wyborZadania* obj = new wyborZadania(numerZad, Zad12);//there is a problem
    delete obj;
}

int main()
{
    Lekcja1 obj(1);
    obj.LekcjaChose();
}
0 голосов
/ 30 января 2020

Указатель на функции-члены передается по-разному. Вам нужно передать его следующим образом:

template<class T>
wyborZadania(int num,void (T::*&tab)()) {
   this->_chose = num;
   switch (_chose)
   {
       case 1:
           (*tab)();
           break;
       default:
           break;
   }
}

Чтобы это работало, Lekcja1 :: tab () должен быть объявлен как stati c, в противном случае вы также должны передать объект. См. живой пример .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...