std ::функция и дружественная функция

#c 11 #friend #std-function

#c 11 #друг #std-функция

Вопрос:

В этом примере у меня есть указатель на функцию (std::function) в качестве атрибута моего класса. Таким образом, я могу связать любую функцию формы void myFunction(void) с моим классом.

 #include <iostream>
#include <functional>

class Example{
private:
    int variable=4;
public:
    std::function<void(void)> myNonMemberFunction;
    Example(void){
    }
    Example(std::function<void(void)> MyNonMemberFunction){
        myNonMemberFunction=MyNonMemberFunction;
    }
};

void PrintPlop(){
    std::cout<<"plop"<<std::endl;
}

int main() {
    Example example(PrintPlop);
    example.myNonMemberFunction();
}
  

Теперь я хочу сделать то же самое, но с функцией, которая имеет доступ к атрибуту класса, например, к функции друга или функции-члену класса. Как я могу это сделать?

Комментарии:

1. не связано: у вас нет указателя (и это хорошо)

Ответ №1:

Итак, вы хотите, чтобы любая функция, которую вы передаете конструктору, стала другом?

В строгом смысле это невозможно, потому что уровень доступа (друг или нет) является проблемой времени компиляции, и какое значение передается конструктору, вообще говоря, определяется только во время выполнения.

Итак, вы либо объявляете все соответствующие функции как друзья (почему бы просто не сделать их методами в этом случае?), Либо передаете им закрытые члены в качестве дополнительных параметров. Вот так:

 class Example{
private:
    int variable=4;
    std::function<void(int)> myNonMemberFunction;
public:
    Example(void){
    }
    Example(std::function<void(int)> MyNonMemberFunction){
        myNonMemberFunction=MyNonMemberFunction;
    }
    void callMyNonMemberFunction() {
      myNonMemberFunction(variable);
    }
};

void PrintPlop(int v){
    std::cout<<"plop"<< v << std::endl;
}

int main() {
    Example example(PrintPlop);
    example.callMyNonMemberFunction();
}
  

Комментарии:

1. Спасибо, это решило мою проблему. Я сделал это, потому что хочу настроить способ управления различными атрибутами моего класса. Для этого я изменил std::function<void(int)> на std::function<void(intamp;)> и это работает.

2. @BaptisteNguyen, рад это знать! И, пожалуйста, обратите внимание, что «спасибо» здесь выражается путем голосования (см. Треугольник в верхнем левом углу моего ответа? щелкните по нему!) и отметив ответ как правильный.