 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
mlepage Guest
|
Posted: Tue Sep 21, 2004 11:36 am Post subject: Value Objects and Temporary Lifetimes? |
|
|
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
|
Posted: Tue Sep 21, 2004 7:03 pm Post subject: Re: Value Objects and Temporary Lifetimes? |
|
|
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
|
Posted: Thu Sep 23, 2004 8:15 am Post subject: Re: Value Objects and Temporary Lifetimes? |
|
|
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 |
|
 |
|
|
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
|
|