Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > class member access operator (->) overloading

Reply
Thread Tools

class member access operator (->) overloading

 
 
Arkaitz Jimenez
Guest
Posts: n/a
 
      05-12-2009
For what I've seen around the operator-> is normally overloaded to
return the inner pointer in the case of a SmartPointer template.
However I was wondering if there is any way of having control after
the access was done, you can always execute code before returning the
pointer but obviously you can't after return.
So, is there anyway to get control before and after operator-> has its
effect?

Thanks

Arkaitz
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      05-12-2009
Arkaitz Jimenez wrote:
> For what I've seen around the operator-> is normally overloaded to
> return the inner pointer in the case of a SmartPointer template.
> However I was wondering if there is any way of having control after
> the access was done, you can always execute code before returning the
> pointer but obviously you can't after return.
> So, is there anyway to get control before and after operator-> has its
> effect?


If I understand correctly what you're after, then no. The overloaded
operator-> returns something (usually a pointer) for which another
operator-> will subsequently be applied. And that's until it's mapped
to the intrinsic operator-> for a pointer to a class object or a pointer
to a non-class object for a pseudo-destructor call.

#include <iostream>
#include <ostream>

using std::cout;

template<class T>
class AuxHasArrow
{
T* t;
public:
AuxHasArrow(T* t) : t(t) {}

T* operator->() { std::cout << "In Aux\n"; return t; }
};

template<class T>
class HasArrow
{
T* t;
public:
HasArrow(T* t) : t(t) {}
AuxHasArrow<T> operator->()
{ std::cout << "In HasArrow\n"; return AuxHasArrow<T>(t); }
};

struct A {
int a;
};

int main()
{
A a = { 42 };
HasArrow<A> ha(&a);

cout << ha->a << "after all\n";
}

See, there is nothing you can squeeze in your class to capture the
control after the operator-> is applied to the address of the 'a' object
(to extract that 42 for output).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      05-12-2009
Stuart Golodetz wrote:
> Arkaitz Jimenez wrote:
>> For what I've seen around the operator-> is normally overloaded to
>> return the inner pointer in the case of a SmartPointer template.
>> However I was wondering if there is any way of having control after
>> the access was done, you can always execute code before returning the
>> pointer but obviously you can't after return.
>> So, is there anyway to get control before and after operator-> has its
>> effect?
>>
>> Thanks
>>
>> Arkaitz

>
> What sort of control are you after? If you just want to execute some
> code after the return, I guess you could always just return an instance
> of another class with an overloaded operator->, which itself executes
> some code and returns the actual pointer. That code would then be
> executing after the original return.


I believe Arkaitz would like to have some code executed after the
intrinsic operator-> is applied to the [actual] pointer (that the op->
returns). I don't think this is possible from within the same class.

> But I'm not sure I understand the
> motivation for doing this in the first place...


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Arkaitz Jimenez
Guest
Posts: n/a
 
      05-12-2009
> If I understand correctly what you're after, then no. *The overloaded
> operator-> returns something (usually a pointer) for which another
> operator-> will subsequently be applied. *And that's until it's mapped
> to the intrinsic operator-> for a pointer to a class object or a pointer
> to a non-class object for a pseudo-destructor call.
>
> ....
> ....
> See, there is nothing you can squeeze in your class to capture the
> control after the operator-> is applied to the address of the 'a' object
> (to extract that 42 for output).
>
> V


Well, that was my idea, that it couldn't be done, at least the way I
wanted to.

Thanks

Arkaitz

 
Reply With Quote
 
Arkaitz Jimenez
Guest
Posts: n/a
 
      05-12-2009
> What sort of control are you after? If you just want to execute some
> code after the return, I guess you could always just return an instance
> of another class with an overloaded operator->, which itself executes
> some code and returns the actual pointer. That code would then be
> executing after the original return. But I'm not sure I understand the
> motivation for doing this in the first place...
>
> Regards,
> Stu


Well, from what I know it's not possible, but just wondering if any
other trick was available.

The idea would be for example to wrap and mutexprotect one object
before and after a member is accessed or a method is executed.

Wraped<myobject> wrapobj;
wrapobj->whatever();
--------------------------
template operator -> would do:

mutex_lock(objolock);
wrapobj->called_method();
mutex_unlock(objlock);

Clearly there is no way of doing that with operator overloading, that
I know at least, but wanted to ask.


Thanks

Arkaitz
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      05-12-2009
On 12 Mai, 15:23, Arkaitz Jimenez <(E-Mail Removed)> wrote:
> For what I've seen around the operator-> is normally overloaded to
> return the inner pointer in the case of a SmartPointer template.
> However I was wondering if there is any way of having control after
> the access was done, you can always execute code before returning the
> pointer but obviously you can't after return.
> So, is there anyway to get control before and after operator-> has its
> effect?


Something like this?


struct do_nothing { void pre(){}; void post(){} };

template<typename T, typename U = T*,
typename prepost_func = do_nothing>
class ptrproxy
{
T* ptr;
public:
explicit ptrproxy(T* p) : ptr(p)
{ prepost_func().pre(); }

~ptrproxy()
{ prepost_func().post(); }

U operator->() const {return U(ptr);}
};

template<typename T, typename PrePost>
struct funky_pointer_metaf {
typedef ptrproxy<T,ptrproxy<T,T*,PrePost> > type;
};

#include <iostream>

struct S {
void blah()
{ std::cout << " --- S::blah ---\n"; }
};

struct my_prepost {
void pre() { std::cout << "prior access\n"; }
void post() { std::cout << "after access\n"; }
};

int main() {
S s;
typedef funky_pointer_metaf<S,my_prepost>::type funky_t;
funky_t p (&s);
p->blah();
p->blah();
}

which outputs:

prior access
--- S::blah ---
after access
prior access
--- S::blah ---
after access

?

Cheers!
SG
 
Reply With Quote
 
Arkaitz Jimenez
Guest
Posts: n/a
 
      05-12-2009
> * struct do_nothing { void pre(){}; void post(){} };
>
> * template<typename T, typename U = T*,
> * * typename prepost_func = do_nothing>
> * class ptrproxy
> * {
> * * T* ptr;
> * public:
> * * explicit ptrproxy(T* p) : ptr(p)
> * * { prepost_func().pre(); }
>
> * * ~ptrproxy()
> * * { prepost_func().post(); }
>
> * * U operator->() const {return U(ptr);}
> * };
>
> * template<typename T, typename PrePost>
> * struct funky_pointer_metaf {
> * * typedef ptrproxy<T,ptrproxy<T,T*,PrePost> > type;
> * };
>
> * #include <iostream>
>
> * struct S {
> * * void blah()
> * * { std::cout << " --- S::blah ---\n"; }
> * };
>
> * struct my_prepost {
> * * void pre() *{ std::cout << "prior access\n"; }
> * * void post() { std::cout << "after access\n"; }
> * };
>
> * int main() {
> * * S s;
> * * typedef funky_pointer_metaf<S,my_prepost>::type funky_t;
> * * funky_t p (&s);
> * * p->blah();
> * * p->blah();
> * }
>
> which outputs:
>
> * prior access
> * *--- S::blah ---
> * after access
> * prior access
> * *--- S::blah ---
> * after access
>
> ?
>
> Cheers!
> SG


Ok, It certainly does what I was looking for, lets see if I understand
it correctly.
You create a temporary sptr inside the original sptr return, that way
you can execute code using the temporary constructor and destructor
routines.
Smart, with this kind of method I'd only need to be careful to not use
throwable code inside the code intended to be executed after the call,
isn't it?

Thanks

Arkaitz


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      05-12-2009
SG wrote:
> On 12 Mai, 15:23, Arkaitz Jimenez <(E-Mail Removed)> wrote:
>> For what I've seen around the operator-> is normally overloaded to
>> return the inner pointer in the case of a SmartPointer template.
>> However I was wondering if there is any way of having control after
>> the access was done, you can always execute code before returning the
>> pointer but obviously you can't after return.
>> So, is there anyway to get control before and after operator-> has its
>> effect?

>
> Something like this?
>
>
> struct do_nothing { void pre(){}; void post(){} };
>
> template<typename T, typename U = T*,
> typename prepost_func = do_nothing>
> class ptrproxy
> {
> T* ptr;
> public:
> explicit ptrproxy(T* p) : ptr(p)
> { prepost_func().pre(); }
>
> ~ptrproxy()
> { prepost_func().post(); }
>
> U operator->() const {return U(ptr);}
> };
>
> template<typename T, typename PrePost>
> struct funky_pointer_metaf {
> typedef ptrproxy<T,ptrproxy<T,T*,PrePost> > type;
> };
>
> #include <iostream>
>
> struct S {
> void blah()
> { std::cout << " --- S::blah ---\n"; }
> };
>
> struct my_prepost {
> void pre() { std::cout << "prior access\n"; }
> void post() { std::cout << "after access\n"; }
> };
>
> int main() {
> S s;
> typedef funky_pointer_metaf<S,my_prepost>::type funky_t;
> funky_t p (&s);
> p->blah();
> p->blah();
> }
>
> which outputs:
>
> prior access
> --- S::blah ---
> after access
> prior access
> --- S::blah ---
> after access
>
> ?


Nice!

It takes advantage of the extra indirection of the operator-> to return
the proxy temporary which will call the post-processing stuff in its
destructor that will be called *at the end of full expression*. I
thought about this, but hadn't find the *temporary* solution, for some
reason I was hung up on local objects, which get destroyed before the
final operator-> is used...

Thank you.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      05-12-2009
* Victor Bazarov:
> SG wrote:
>> On 12 Mai, 15:23, Arkaitz Jimenez <(E-Mail Removed)> wrote:
>>> For what I've seen around the operator-> is normally overloaded to
>>> return the inner pointer in the case of a SmartPointer template.
>>> However I was wondering if there is any way of having control after
>>> the access was done, you can always execute code before returning the
>>> pointer but obviously you can't after return.
>>> So, is there anyway to get control before and after operator-> has its
>>> effect?

>>
>> Something like this?
>>
>>
>> struct do_nothing { void pre(){}; void post(){} };
>>
>> template<typename T, typename U = T*,
>> typename prepost_func = do_nothing>
>> class ptrproxy
>> {
>> T* ptr;
>> public:
>> explicit ptrproxy(T* p) : ptr(p)
>> { prepost_func().pre(); }
>>
>> ~ptrproxy()
>> { prepost_func().post(); }
>>
>> U operator->() const {return U(ptr);}
>> };
>>
>> template<typename T, typename PrePost>
>> struct funky_pointer_metaf {
>> typedef ptrproxy<T,ptrproxy<T,T*,PrePost> > type;
>> };
>>
>> #include <iostream>
>>
>> struct S {
>> void blah()
>> { std::cout << " --- S::blah ---\n"; }
>> };
>>
>> struct my_prepost {
>> void pre() { std::cout << "prior access\n"; }
>> void post() { std::cout << "after access\n"; }
>> };
>>
>> int main() {
>> S s;
>> typedef funky_pointer_metaf<S,my_prepost>::type funky_t;
>> funky_t p (&s);
>> p->blah();
>> p->blah();
>> }
>>
>> which outputs:
>>
>> prior access
>> --- S::blah ---
>> after access
>> prior access
>> --- S::blah ---
>> after access
>>
>> ?

>
> Nice!
>
> It takes advantage of the extra indirection of the operator-> to return
> the proxy temporary which will call the post-processing stuff in its
> destructor that will be called *at the end of full expression*. I
> thought about this, but hadn't find the *temporary* solution, for some
> reason I was hung up on local objects, which get destroyed before the
> final operator-> is used...
>
> Thank you.


SG didn't provide a reference, but Bjarne once wrote a paper about exactly the
above technique.

So, let's also thank Bjarne Stroustrup.

Of course, some soul that-I-don't-recall-the-name-of at Microsoft should perhaps
also be thanked for the "COM call interceptor" which, even though it's not only
system specific but also technology specific, for what it does is more general.

And then also thanks to the folks at ParkPlace for the even more general C++
language extension or preprocessor or whatever it was that provides general call
interceptors for implemention of cross-code concerns (like e.g. logging); they
also should be thanked for the Smalltalk project when they were at Xerox PARC.

Argh, I cannot remember the name for that last technique!


Cheers,

- Alf


--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      05-12-2009
On 12 Mai, 16:39, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>
> SG didn't provide a reference


Right. I can't take credit for that (except for the attempt to use
exactly one class template instead of two with overloaded operator->()
to shorten the example). But I have no reference handy. I think I saw
it on someone's blog where the author used it for locking a mutex. I
probably wouldn't use it for locking, though.

> but Bjarne once wrote a paper about exactly the
> above technique.
>
> So, let's also thank Bjarne Stroustrup.


Is it publicly available?

Cheers!
SG
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why is overloading operator. (member operator) forbidden? dascandy@gmail.com C++ 11 05-16-2007 07:54 PM
Problem with member and non-member binary operator in template class ghager C++ 6 01-19-2006 11:32 AM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Can Derived class static member access protected member from base class? Siemel Naran C++ 4 01-12-2005 06:46 PM
protected member class and operator overloading Thomas C++ 3 09-21-2004 02:15 AM



Advertisments