Re: hiding function call under the "instance->member" notation
* viki:
We have zillion of instances inf instance->m_member in the code.
We are going introduce the 'accessors' Get() and Set() for m_member,
and
m_member going private (and renamed, too). We would like to leave, if
possible,
refs inst->m_member in the code, but make compiler translate
it to inst->Get() invisily, and without using macros. Let's assume T
is
a type of m_member.
Is there any c++ trick to redirect inst->m_foo /* no parentheses
after m_foo */
to function call inst->Get(), without using macros ? I am sure there
is some
trick of declaring m_foo a special small class that evaluates a
function
when accessed, but I can't figure it out.
Apparently semi-possible with #define (only outside of the class):
#define m_member Get()
but that sucks
(you do not need to enumerate all reasons why it sucks, we are not
going to use it; this just to illustrates equivalent of what we
want).
We do not want to use macro, we want the C++ equivalent.
As others have remarked else-thread, what you have is a very foul design-smell.
However, at the technical level (this is perhaps akin to answering a question
about how to use goto, and note that the language constructs involved are at the
same level):
<code>
#include <iostream> // std::cout, std::ostream
#include <ostream> // operator<<, std::endl
#include <memory> // std::auto_ptr
#ifdef _MSC_VER
#pragma warning( disable: 4355 ) // 'this' used in initializer list.
#endif
class Foo
{
public:
int member;
Foo(): member( 42 ) {}
};
class Bar
{
private:
template<
typename T,
void (Bar::*set)( T const& ),
T (Bar::*get)() const
>
class GetSetProxy
{
private:
Bar* myBar;
public:
GetSetProxy( Bar* pBar ): myBar( pBar ) {}
GetSetProxy& operator=( T const& v )
{
(myBar->*set)( v ); return *this;
}
operator T() const { return (myBar->*get)(); }
};
int myMember;
void setMember( int const& x ) { myMember = x; }
int getMember() const { return myMember; }
typedef GetSetProxy<int, &Bar::setMember, &Bar::getMember> Member;
public:
Member member;
Bar(): myMember( 42 ), member( this ) {}
};
int main()
{
using namespace std;
std::auto_ptr<Foo> pFoo( new Foo );
pFoo->member = 666;
cout << pFoo->member << endl;
std::auto_ptr<Bar> pBar( new Bar );
pBar->member = 777;
cout << pBar->member << endl;
}
</code>
Note that GetSetProxy::operator=() isn't 'const', because in this particular
scenario, although assignment doesn't modify the proxy object, the constness of
the containing object is transferred to the proxy and should determine whether
assignment is allowed.
Cheers, & hope you tackle the design rather than doing silly things like above,
- Alf