Как изменить функцию класса для каждого его объекта?

159
24 октября 2018, 12:10

Можно ли изменить функцию, объявленную в классе, для каждого его объекта по своему, и если можно то как это сделать?

Answer 1

Функцию класса для каждого объекта не изменить - адрес такой функции прописывается либо при компиляции, либо в таблице виртуальных функций, и для всех объектов одинаков.

Другое дело, что можно хранить указатели на функции (или, скажем, объекты function<>) в объектах класса и вызывать их. Что-то вроде

class Horror
{
public:
    Horror(function<void(void)> f):f(f){}
    void operator()() { f(); }
private:
    function<void(void)> f;
};

void out() { cout << "Out\n"; }
int main(int argc, const char * argv[])
{
    Horror h1(out), h2([](){ cout << "Lambda\n"; });
    h1();
    h2();
}
Answer 2

В дополнение к посту Harry, работающий вариант с указателями на функции.

#include <iostream>
typedef void (*func_ptr)(int);
class TestClass {
public:
    func_ptr  method;
};
void method_plus(int _arg) {
    std::cout << _arg + 1 << std::endl;
}
void method_minus(int _arg) {
    std::cout << _arg - 1 << std::endl;
}
int main() {
    TestClass tc1, tc2;
    tc1.method = method_plus;
    tc2.method = method_minus;
    tc1.method(42);
    tc2.method(42);
    return EXIT_SUCCESS;
}

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

Не очень понятна задача, зачем это нужно; с конкретным примером было бы понятнее.

UPD: Этот же вариант, но с передачей функции в конструктор при создании объекта:

#include <iostream>
typedef void (*func_ptr)(int);
class TestClass {
public:
    TestClass(func_ptr _ptr);
public:
    func_ptr  method;
};
TestClass::TestClass(func_ptr _ptr) : method(_ptr) {
}
void method_plus(int _arg) {
    std::cout << _arg + 1 << std::endl;
}
void method_minus(int _arg) {
    std::cout << _arg - 1 << std::endl;
}
int main() {
    TestClass tc1(method_plus), tc2(method_minus);
    tc1.method(42);
    tc2.method(42);
    return EXIT_SUCCESS;
}
Answer 3

Можно, но так как ваша кокретная цель неизвестна, я приведу простой пример:

class Sample_class {
    static int k;
    int n;
    void f() { cout << " f" << n << ' ' ; }
public:
    Sample_class()  { n = k++;  }
    void some_function(){
       for (int i = 0; i <= n; ++i)
           f();
    }
};
int Sample_class::k = 0;
int main()
{   
    Sample_class x, y, z;
    x.some_function();
    cout << endl;
    y.some_function();
    cout << endl;
    z.some_function();
    return 0;
}
READ ALSO
Как в QT5 в QTableWidget из делегата изменить значение в ячейке из другой колонки?

Как в QT5 в QTableWidget из делегата изменить значение в ячейке из другой колонки?

Задача следующая: ComboBoxDelegate задает точность и шаг приращения в другой колонке той же строки, но с DoubleSpinBoxDelegateПроблема в том, что если изменить...

162
Вызов перегруженной функции - Segmentation fault

Вызов перегруженной функции - Segmentation fault

При вызове Func() заполняется buffer данными из сокета, после происходит их конвертация в класс DerivedЕсли после конвертаци вызвать функию Foo(), то происходит...

153