Topic: Guru of the Week #22: Object Lifetimes - Part I
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/13 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
|> Does it means that references *are* rebindable ? It would be
|> the contrary of what everyone tell everyday.
|>
|> int i, j, &r = i;
|> new (&r) int& (j);
|>
|> I think a clarification in the DWP (as a note) can't hurt.
Nothing to clarify here -- the above code is illegal, and will fail on
many machines. Note that the expression &r returns the address of the
referred to value (in this case, i), and not the address of the
reference.
A reference cannot be reseated during its lifetime. However, if the
reference is part of a larger object (a struct), then its lifetime is
that of the larger object -- explicitly calling the destructor on the
object, and then reconstructing it, causes the original reference to
cease to exist, and creates a new one. In fact, I think that just
reconstructing an object with a reference, without destructing it first,
is guaranteed to work.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/10/14 Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
> A reference cannot be reseated during its lifetime. However, if the
> reference is part of a larger object (a struct), then its lifetime is
> that of the larger object -- explicitly calling the destructor on the
> object, and then reconstructing it, causes the original reference to
> cease to exist, and creates a new one. In fact, I think that just
> reconstructing an object with a reference, without destructing it first,
> is guaranteed to work.
Surprisingly, yes, you can rebind a reference variable during its lifetime.
To put James's words into code:
class Foo
{
public:
Foo();
Foo(int &x) ref(x) { }
private:
int & ref; // A reference
};
void foobar()
{
int x = 1;
int y = 2;
Foo obj(x); // obj.ref is bound to x
obj.~Foo(); // obj is destructed in place
new((void *)&obj) Foo(y); // obj.ref is rebound to y
}
Note that the destructor call is not mandatory (but it's probably a really
good idea).
Can a class containing a reference variable (such as 'Foo' above) rebind
the reference itself? This is probably legal:
void Foo::rebind(int &x)
{
this->~Foo(); // Criminy!
new((void *)this) Foo(x); // this->ref is rebound to x
}
Is this a good idea? That's a different question. Probably not.
-- David R. Tribble, david.tribble@beasys.com --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/15 Raw View
J. Kanze <kanze@gabi-soft.fr> writes:
> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> |> Does it means that references *are* rebindable ? It would be
> |> the contrary of what everyone tell everyday.
> |>
> |> int i, j, &r = i;
> |> new (&r) int& (j);
> |>
> |> I think a clarification in the DWP (as a note) can't hurt.
>
> Nothing to clarify here -- the above code is illegal, and will fail on
> many machines. Note that the expression &r returns the address of the
> referred to value (in this case, i), and not the address of the
> reference.
Sorry, sorry, sorry (that's correct, how did I missed that ?)
It is very clear in the above code, but not in the following case:
> A reference cannot be reseated during its lifetime. However, if the
> reference is part of a larger object (a struct), then its lifetime is
> that of the larger object -- explicitly calling the destructor on the
> object, and then reconstructing it, causes the original reference to
> cease to exist, and creates a new one.
_This_ should be made clear in the WP. It means that references
aren't const (and that T& const could means non-resetable reference
to T).
I call that a reseatable reference.
It should be explicitly written in the std.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/15 Raw View
David R Tribble wrote:
> Expanding on the theme of rebinding (or 'reseating') reference variables,
> I've cooked up a little more complicated example:
>
> class Foo
> {
> public:
> Foo(int &i, double &d);
>
> void reseatI(int &x); // See below
> void reseatD(double &x); // See below
>
> private:
> int & iRef; // A reference member
> double & dRef; // Another reference member
>
> Foo(int &o): iRef(o) { }
> Foo(double &o): dRef(o) { }
Sorry this is ill-formed: you must have all the members which
require innitilisation in your list (all const and references
members).
Perhaps you mean:
Foo(int &o): iRef(o), dRef(dRef) { }
> Is this a good idea? On the one hand, it allows you to treat references
> like mutable pointers. On the other hand, it breaks the implicit
> guarantee that a reference does not (or should not) change its binding
> once it has been instantiated.
I think it's a good beginning for a IOC++CC entry (when it will exists).
(For info on IOCCC, go to: http://reality.sgi.com/csp/ioccc/index.html.)
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/10/15 Raw View
Expanding on the theme of rebinding (or 'reseating') reference variables,
I've cooked up a little more complicated example:
class Foo
{
public:
Foo(int &i, double &d);
void reseatI(int &x); // See below
void reseatD(double &x); // See below
private:
int & iRef; // A reference member
double & dRef; // Another reference member
Foo(int &o): iRef(o) { }
Foo(double &o): dRef(o) { }
};
Foo::Foo(int &i, double &d):
iRef(i), dRef(d) // Bind the reference members
{
...whatever...
}
void Foo::reseatI(int &o)
{
// Do not destruct *this
new((void *)this) Foo(o); // Rebinds this->iRef to o
}
void Foo::reseatD(double &o)
{
// Do not destruct *this
new((void *)this) Foo(o); // Rebinds this->dRef to o
}
The private constructors of class Foo exist solely to allow for rebinding
the reference members of the class.
Clients of class Foo can create a Foo object with an initial binding to
two variables (an int and a double) and then change the reference bindings
by calling reseatI() and reseatD():
void myFunc()
{
int i;
double x;
Foo obj(i, x); // obj.iRef bound to i,
// obj.dRef bound to x
int j;
obj.reseatI(j); // obj.iRef now bound to j
double y;
obj.reseatD(y); // obj.dRef now bound to y
}
There's also the consideration of what happens when the private
constructors are invoked if Foo is a derived class; constructors for
the base class(es) may be invoked also. If the base class contains
reference member variables, they can also be re-bound using the same
technique.
Is this a good idea? On the one hand, it allows you to treat references
like mutable pointers. On the other hand, it breaks the implicit
guarantee that a reference does not (or should not) change its binding
once it has been instantiated.
--------------------. BEA Systems, Inc. ,-. +1-972-738-6125 Office
David R. Tribble \ ,------------------' \ +1-972-738-6111 Fax
http://www.beasys.com `-' Dallas, TX 75248 `-----------------------
david.tribble@noSPAM.beasys.com http://www.flash.net/~dtribble
Support the anti-Spam amendment, join at http://www.cauce.org/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]