C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Value Objects and Temporary Lifetimes?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
mlepage
Guest





PostPosted: Tue Sep 21, 2004 11:36 am    Post subject: Value Objects and Temporary Lifetimes? Reply with quote



I have some code that has a global two dimensional array of structs
with member variables, used like this:

array[i][j].member = 42;

Consider the following series of changes:

1) Global array becomes global object with operator[] overloaded to
return a second object initialized with argument i.

2) That second object has operator[] overloaded to return a third
object initialized with arguments i and j.

3) That third object has function member() which returns a fourth
object initialized with arguments i and j, and a code for member.

4) That fourth object has operator= overloaded to take arguments i, j,
the code for member, and the int argument, and go off in a database to
set the appropriate value using that information.

So basically, the big global array of structs is replaced by a bunch
of magic to store it all in a database instead. Temporary value
objects do the work. Here's the code:

struct GlobalObject
{
SecondObject operator[](int n1) { return SecondObject(n1); }
};

struct SecondObject
{
SecondObject(int n1) : m_n1(n1) {}
ThirdObject operator[](int n1) { return ThirdObject(m_n1, n2); }
const int m_n1;
};

struct ThirdObject
{
ThirdObject(int n1, n2) : m_n1(n1), m_n2(n2) {}
FourthObject member() { return FourthObject(m_n1, m_n2,
MEMBER_CODE); }
const int m_n1;
const int m_n2;
};

struct FourthObject
{
FourthObject(int n1, int n2, int n3) : m_n1(n1), m_n2(n2),
m_n3(n3) {}
FourthObject& operator=(int n)
{
// use all this info to set something in a database to n
return *this;
}
const int m_n1;
const int m_n2;
const int m_n3;
};

The global object is now declared like this:

GlobalObject array;

So now the use is like this (only a minor difference in syntax):

array[i][j].member() = 42;

I've tested this and it seems to work as expected.

My question is, are there any problems with this approach? Will the
temporaries live long enough to ensure that the assignment (which does
work in a database) is using valid data?

(I think it is, but I want to double check, since my application has
some weird errors that puzzle me. I want to ensure that this approach
is valid before I rule it out as a possible cause.)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ben Hutchings
Guest





PostPosted: Tue Sep 21, 2004 7:03 pm    Post subject: Re: Value Objects and Temporary Lifetimes? Reply with quote



mlepage wrote:
Quote:
I have some code that has a global two dimensional array of structs
with member variables, used like this:

array[i][j].member = 42;

Consider the following series of changes:

1) Global array becomes global object with operator[] overloaded to
return a second object initialized with argument i.

2) That second object has operator[] overloaded to return a third
object initialized with arguments i and j.

3) That third object has function member() which returns a fourth
object initialized with arguments i and j, and a code for member.

4) That fourth object has operator= overloaded to take arguments i, j,
the code for member, and the int argument, and go off in a database to
set the appropriate value using that information.
snip
My question is, are there any problems with this approach? Will the
temporaries live long enough to ensure that the assignment (which does
work in a database) is using valid data?

(I think it is, but I want to double check, since my application has
some weird errors that puzzle me. I want to ensure that this approach
is valid before I rule it out as a possible cause.)

The temporaries will be destroyed at the end of the statement. So
long as operator= in the fourth object does not store a reference
to any of the temporaries for later use this approach should be
fine.

--
Ben Hutchings
The generation of random numbers is too important to be left to chance.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Maxim Yegorushkin
Guest





PostPosted: Thu Sep 23, 2004 8:15 am    Post subject: Re: Value Objects and Temporary Lifetimes? Reply with quote



mlepage <antimeta (AT) gmail (DOT) com> wrote:

Quote:
I have some code that has a global two dimensional array of structs
with member variables, used like this:

array[i][j].member = 42;

Consider the following series of changes:

1) Global array becomes global object with operator[] overloaded to
return a second object initialized with argument i.

2) That second object has operator[] overloaded to return a third
object initialized with arguments i and j.

3) That third object has function member() which returns a fourth
object initialized with arguments i and j, and a code for member.

4) That fourth object has operator= overloaded to take arguments i, j,
the code for member, and the int argument, and go off in a database to
set the appropriate value using that information.

[]

Quote:
My question is, are there any problems with this approach?

For me, it looks like you've got too many objects to do the job.

Using just two classes you can achive the goal without even changing the
syntax for accessing the members of the elements of the array. Here is an
example:

template<class T, class Object>
class smart_member
{
public:
smart_member(Object* obj) : obj_(obj) {}

operator T const() const
{
int i(obj_->index_i());
int j(obj_->index_j());
obj_->reset_indexes();

/*do some stuff to retreive a value*/
std::cout << __FUNCTION__ << " : " << i << ", " << j << 'n';

return T();
}
smart_member& operator=(T const&)
{
int i(obj_->index_i());
int j(obj_->index_j());
obj_->reset_indexes();

/*do some stuff to store the value*/
std::cout << __FUNCTION__ << " : " << i << ", " << j << 'n';

return *this;
}

private:
Object* obj_;
};

class array_like
{
public:
array_like() : i(this), d(this) { this->reset_indexes(); }

// add sanity checks that pind_ does not get out of bounds
array_like& operator[](int i) { *pind_++ = i; return *this; }
array_like const& operator[](int i) const { *pind_++ = i; return
*this; }

smart_member<int, array_like> i;
smart_member<double, array_like> d;

private:
template<class, class> friend class smart_member;

// add sanity checks that pind_ is properly positioned
int index_i() const { return ind_[0]; }
int index_j() const { return ind_[1]; }
void reset_indexes() const { pind_ = ind_; }

private:
mutable int ind_[2];
mutable int* pind_;
};

array_like array;

int main()
{
array[1][2].i = 13;
array[3][4].d = 22/7.0;

int i = array[1][2].i;
double d = array[3][4].d;
}

The drawback in this example is that a compiler won't catch you if you use
a wrong number of subscript operators while accessing an array_like
object, that is why the sanity checks may be required to catch those
errors at runtime.

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.