2012-04-13 2 views
-1

В C++, как я могу вызвать члена класса класса A из класса B с помощью указателя? Кстати, класс А и В имеют разные типы.Указание переменной на функцию-член из другого типа класса

Я читал, что, когда указатель указывает на функцию-член, он может только указывать функции-члены внутри класса. Но как я могу указать на функцию-член вне класса?

, например:

class A 
{ 
public: 
    int add(int x) 
    { 
     return x+x; 
    } 
}; 

int main() 
{ 
    typedef int (A::*pointer)(); 
    pointer func = &A::add; 
    A objt; 
    B objt2; 

    obt2.*func(2);// the compiler give me an error of incompatible with object type ‘B’ 

    return 0; 
} 
+0

Try '(2)' –

+5

@Chet: Это не решает тот факт, что вызов в 'функции члена Ā' на экземпляре 'B' является бессмысленным. – ildjarn

+1

Независимо от того, какую проблему вы пытаетесь решить с помощью этой концепции, вероятно, легче решить и * лучше * использовать другой подход. В C++ методы и функции являются одними и теми же, в отличие от Smalltalk и других чистых языков OO. Перестройте свое решение, чтобы использовать практические функции языка, такие как наследование или какой-либо шаблон дизайна, который достигает вашего конца. Если вы разделяете свою фактическую цель, кто-то может предложить некоторые действительные подходы. –

ответ

0

Я думаю, что вы можете запустить его следующим образом:

(*func)(&objt, 2) 

Лучше выбор будет использовать повышение :: BIND/повышение :: функции вместо:

boost::function<int(int)> func = boost::bind(&A::add, &objt, _1); 
func(2); 

Я только заметил, что вы пытаетесь запустить его, как если бы это был метод класса B. Это абсолютно бессмысленно, но если вы не заботитесь о правильности и любите опасно жить с совершенно непредсказуемыми результатами, это легче сделать это:

((A *) &objt2)->add(2); 
+0

Я сам не объяснил свое само собой разумеющееся. Мой вопрос не @Chet ildjarn. Я реализую класс в omnetpp. Этот класс определяет модуль в моей симуляции. Я хочу получить доступ к методу с помощью указателя. Этот метод реализуется в другом классе, который определяет еще один MO-график в моей симуляции. – Vilanova

+3

«чувак», ваш вопрос неправ. –

+0

Если 'A' и' B' не имеют отношения, разыменование (A *) & objt2' дает UB. – ildjarn

0

Если B использует A (называет членом некоторых A «s), то Bзависит от от A, и вы можете реализовать это, просто указав B с указателем на A, с помощью которого он может вызвать методы A - см. Класс B1 ниже в коде.

Вы можете обернуть звонок члена A в отдельный объект - функтор. Вы можете создать общее решение, выполнив его как класс шаблона и указав адрес объекта A, адрес метода и аргумента. Для этого см. Реализацию класса B2.

class A 
{ 
public: 
    int add(int x) 
    { 
     return x+x; 
    } 
}; 

typedef int (A::*MEMFN)(int); 

class B1 
{ 
public: 
    void InvokeAAdd(A* pA, int x) 
    { 
     cout << "result = " << pA->add(x) << endl; 
    } 
}; 

template<class T, typename TMemFn, typename TArg, typename TRetVal> 
class B2 
{ 
    T* pT; 
    TMemFn memFn; 
    TArg arg; 
public: 
    B2(T* pT, TMemFn memFn, TArg arg) : 
     pT(pT), memFn(memFn), arg(arg){} 

    TRetVal operator()() 
    { 
     return (pT->*memFn)(arg); 
    } 
}; 

int main() 
{ 
    A a; 
    B1 b; 
    b.InvokeAAdd(&a, 2); 

    B2<A, MEMFN, int, int> b2(&a, &A::add, 2); 
    cout << "result (via functor) = " << b2() << endl; 
    return 0; 
} 

Выход: (. Obt2 * FUNC)

result = 4 
result (via functor) = 4 
Смежные вопросы