Click to See Complete Forum and Search --> : 4 questions about ->* overload


walkinginwater
December 3rd, 2004, 11:14 AM
I have 4 question about the operator ->* overloading:
first:The operator–>* is a binary operator
but when we define the implementation of it we just take one argument, i don't know why , can somebody give me an explanation?
Second:From the following example, i have no idea about the usefulness of ->*overloading,it is too troublesome to create the FunctionObject class. Can we just forbidden the overloading of it??
third:why the statement "w->pmf*" can work?
the output of this is : operator->*
FunctionObject constructor
Fourth:why we cannot use the statement: w->*pmf(12);



#include <iostream>
using namespace std;

class Dog
{
public:
int run(int i) const
{ cout << "run\n";
return i;
}
typedef int (Dog::*PMF)(int) const;//define the pointer to the member function

class FunctionObject // operator->* must return an object that has an operator(),
{ //so we should first create a class to store the information
private: // that we need to implement the () function
Dog* ptr; PMF pmem;
public:
FunctionObject(Dog* wp, PMF pmf) : ptr(wp), pmem(pmf)
{ cout << "FunctionObject constructor\n"; }

int operator()(int i) const
{ cout << "FunctionObject::operator()\n";
return (ptr->*pmem)(i); // Make the call
}
};
//the definition of the operator->* overloading
FunctionObject operator->*(PMF pmf)
{ cout << "operator->*" << endl;
return FunctionObject(this, pmf);
}
};

int main()
{ Dog w;
Dog::PMF pmf = &Dog::run;
cout << (w->*pmf)(1) << endl;
w->pmf*;//why this can work
//w->pmf*(12) //error C2064: term does not evaluate to a function taking 1 arguments
} ///:~

MrViggy
December 3rd, 2004, 11:56 AM
What does 'operator->*' do? I'm not familiar with this operator (as a single operator, and not 'operator->' and 'operator *').

Viggy

Marc G
December 3rd, 2004, 12:18 PM
What does 'operator->*' do? I'm not familiar with this operator (as a single operator, and not 'operator->' and 'operator *').
It's the most obscure operator of C++, and almost never used.
It's a pointer to member operator. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/operator_29.asp

MrViggy
December 3rd, 2004, 12:21 PM
Wow, that's annoying!

:)

So, in their (MSDN) example:
(pObject->*pMemberFunc) (6);
Is this the same as:
(*(pObject->pMemberFunc))(6);
Viggy

Marc G
December 3rd, 2004, 12:47 PM
No, ->* or .* is 1 operator for pointer to a member function of a class. But I don't know the details myself.
Apparently MS even removed some example that is present in my offline MSDN. I'll post it below:
// expre_Expressions_with_Pointer_Member_Operators.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;

class Testpm {
public:
void m_func1() { cout << "m_func1\n"; }
int m_num;
};

// Define derived types pmfn and pmd.
// These types are pointers to members m_func1() and
// m_num, respectively.
void (Testpm::*pmfn)() = &Testpm::m_func1;
int Testpm::*pmd = &Testpm::m_num;

int main() {
Testpm ATestpm;
Testpm *pTestpm = new Testpm;

// Access the member function
(ATestpm.*pmfn)();
(pTestpm->*pmfn)(); // Parentheses required since * binds
// less tightly than the function call.

// Access the member data
ATestpm.*pmd = 1;
pTestpm->*pmd = 2;

cout << ATestpm.*pmd << endl
<< pTestpm->*pmd << endl;
}

Output of the above code:
m_func1
m_func1
1
2

In the preceding example, a pointer to a member, pmfn, is used to invoke the member function m_func1. Another pointer to a member, pmd, is used to access the m_num member.


Another example:
// expre_Expressions_with_Pointer_Member_Operators2.cpp
// C2440 expected
class BaseClass
{
public:
BaseClass(); // Base class constructor.
void Func1();
};

// Declare a pointer to member function Func1.
void (BaseClass::*pmfnFunc1)() = &BaseClass::Func1;

class Derived : public BaseClass
{
public:
Derived(); // Derived class constructor.
void Func2();
};

// Declare a pointer to member function Func2.
void (Derived::*pmfnFunc2)() = &Derived::Func2;

int main()
{
BaseClass ABase;
Derived ADerived;

(ABase.*pmfnFunc1)(); // OK: defined for BaseClass.
(ABase.*pmfnFunc2)(); // Error: cannot use base class to
// access pointers to members of
// derived classes.
(ADerived.*pmfnFunc1)(); // OK: Derived is unambiguously
// derived from BaseClass.
(ADerived.*pmfnFunc2)(); // OK: defined for Derived.
}

The result of the .* or –>* pointer-to-member operators is an object or function of the type specified in the declaration of the pointer to member. So, in the preceding example, the result of the expression ADerived.*pmfnFunc1() is a pointer to a function that returns void. This result is an l-value if the second operand is an l-value.

MrViggy
December 3rd, 2004, 02:40 PM
Thanks. Still seems rather confusing to me.

:D

Viggy

Marc G
December 6th, 2004, 12:23 PM
Thanks. Still seems rather confusing to me.

:D

Viggy
Yes, I wouldn't advise to use them ;)
If you need pointer to member functions, just use something like boost::bind, which is much better in my opinion. :wave: