Error passing a method to another method. C++

Asked

Viewed 292 times

1

I am a beginner in programming and decides to venture into a project with some friends, in it I need the program descending which the order of the routine based on a factor, I am passing to a smaller chained list to facilitate the organization and have to deal with the whole class.
However I am finding problem to pass the method to function. Follow an example code:

#include <iostream>
#include <string>

using namespace std;

class Txt
{
    string palavra;
    int tam;
public:
    void load(string txt) { palavra = txt; tam = txt.length(); }
    void print() { cout << palavra << endl; };
    int w_tam() { return tam; }
};

class Info2
{
public:
    int tam;
    void (*print)();
};

Info2 redirecionar(Txt txt)
{
    Info2 info;
    info.tam = txt.w_tam();
    info.print = &(txt.print); // aqui acontece um erro
    return info;
}

int main()
{
    Txt A, B;
    A.load("Amor");
    B.load("Bolota");

    Info2 AA, BB;
    AA = redirecionar(A);
    BB = redirecionar(B);

    if (AA.tam > BB.tam)
    {
        AA.print();
    }
    else
    {
        BB.print();
    }
}

I use VS2017, and error has the following description: '&' invalid operation in the associated member function expression. But I could not understand, I saw the same idea in another topical in C.

  • 1

    You need to decide whether to do it in C++ or C. This code mixes the two things.

  • The guy from Txt::print is not void (*)(), and yes void (Txt::*)().

  • The idea would be to do this in C++, as I do?

1 answer

1

The guy from Txt::print is not void (*)(), and yes void (Txt:: *)().

Change the type of print in class Info2:

class Info2
{
public:
    int tam;
    void (Txt:: *print)();
};

And assign the address of the member function:

info.print = &Txt::print;

Also save the instance of a Txt, because a member function can only be called with a valid class instance.

To call the member function, use the Operator .* (or ->* in the case of Info2 be accessible by a pointer only) together with the instance of a Txt:

auto print = AA.print;
(A.*print)(); // Ou (A.*AA.print)();

Note the parentheses around A.*print: the precedence of a function call is greater than that of the operator .*, then parentheses are needed.

If you want to avoid this syntax and not mind dynamic allocations, you can make use of std::function to store the method call inside a lambda:

#include <functional>

class Info2
{
public:
    int tam;
    std::function<void()> print;
};

Info2 redirecionar(Txt &txt)
{
    Info2 info;
    // ...
    info.print = [&txt] { txt.print(); };
    // ...
}

// ..
AA.print();
  • The idea in this case would be not to make a copy of the function but to make reference to it, with it being able to reference its members (which may vary) and it keeps changing, however only with another name. It is possible or breaks the encapsulation?

  • Just change the passage by value to pass by reference.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.