ps-create
ps-create

Reputation: 23

pass function to class as parameter C++

there is error here(but when i try to send non //class function its workin); like when i try to add normal void zad1(){somethin...} its works but when i try to add function from class its not :?

 //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() {}
    };

Upvotes: 1

Views: 308

Answers (3)

Raviteja Narra
Raviteja Narra

Reputation: 456

a non-static method cannot be sent as an argument without specifying the object of the class.

Below code uses std::function() to acheive this in simple code.

#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();
}

Upvotes: 0

parktomatomi
parktomatomi

Reputation: 4079

tab is a method of Lekcja1, which is different from a regular function because it needs access to all the data members of Lekcja1.

You can either make Lekcja1::tab a static method, which hides access to data member and makes it a normal function:

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

Or if you need tab to access data members of Lekcja1, then the wyborZadania constructor should take a pointer-to-member of Lekcja1 and an instance of Lekcja1, instead of a function pointer:

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

If you need that to be more flexible or accept different kinds of classes, then wyborZadania should take an std::function, which is a rich wrapper around a function that will let you bind arguments and data.

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

And then in LekcjaChose() pass a lambda to call tab():

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

demo: https://godbolt.org/z/XfwpSJ

Upvotes: 1

StefanKssmr
StefanKssmr

Reputation: 1226

Pointer to member functions are passed differently. You need to pass it like this:

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

For this to work Lekcja1::tab() should be declared static, otherwise you also have to pass an object, too. See the live example.

Upvotes: 0

Related Questions