Am I correct in think that you can't re-assign a reference to a different
object? If so, what should happen here:
struct A
{
DoSomeThing();
};
A& GetNextA();
while (1)
{
A& a = GetNextA();
a.DoSomeThing();
}
Does reference 'a' only get assigned first time around the loop and,
thereafter, object 'a' gets assigned to the next 'A'... or is 'a' connected
to a different 'A' every time around the loop? What about this:
while (1)
{
{
A& a = GetNextA();
a.DoSomeThing();
}
}
Surely, 'a' would now be different every time around the loop (because the
scope of 'a' ends before looping?
On a related note, is it possible to prevent a reference to a class
instance? Similarly, is it possible to prevent the address of an instance
from being taken?
What I'm looking for is a way to implement a 'Reference<T>' class. In other
words, some kind of class like a smart-pointer except that the 'Reference'
is the only way to access the object to which it refers. I want to prevent
'address-of' and references and use the 'Reference' as a means to manage
object life-time.
Any insight or links to good articles will be very much appreciated.
Regards
Tim 29 1860
"Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message news:40*********************@dread11.news.tele.dk. .. while (1) { A& a = GetNextA();
a.DoSomeThing(); }
Since "a" is not declared static, it gets initalized everytime code passes through
the block.
while (1) { { A& a = GetNextA();
a.DoSomeThing(); } }
The extra { } have no additional effect here.
On a related note, is it possible to prevent a reference to a class instance? Similarly, is it possible to prevent the address of an instance from being taken?
You can't do anything to prevent a value from being bound to a reference.
You can make taking the address of it difficult, by overloading the unary
& operator for the class, but I'm not certain that would be a fool proof
way of disabling it entirely. What I'm looking for is a way to implement a 'Reference<T>' class. In other words, some kind of class like a smart-pointer except that the 'Reference' is the only way to access the object to which it refers. I want to prevent 'address-of' and references and use the 'Reference' as a means to manage object life-time.
I'm unclear of what you're really trying to accomplish, however provided you don't
specifically provide a way to do with it, a Reference<T> wouldn't be bindable to T&.
However such a class would have other problems. Specifically, you can't overload
operator (period). .
Tim Clacy wrote: Am I correct in think that you can't re-assign a reference to a different object? If so, what should happen here:
Yes.
[snip] { A& a = GetNextA();
a.DoSomeThing(); }
The object "a" only exists within this scope. Once the scope is left it
should be destroyed. When the loop re-enters the scope a new object,
also called "a", will be created.
I suppose compiler optimisations might change this behaviour in some
unnoticeable way.
Note that I'm not certain about any of this. You could always try it and
see what your compiler does.
Does reference 'a' only get assigned first time around the loop and, thereafter, object 'a' gets assigned to the next 'A'... or is 'a' connected to a different 'A' every time around the loop? What about this:
while (1) { { A& a = GetNextA();
a.DoSomeThing(); } }
Call me crazy, but isn't that identical to the last bit of code? You're
just adding an extra (redundant) scope.
Surely, 'a' would now be different every time around the loop (because the scope of 'a' ends before looping?
Yes, I'm pretty sure they are the same.
On a related note, is it possible to prevent a reference to a class instance? Similarly, is it possible to prevent the address of an instance from being taken?
What I'm looking for is a way to implement a 'Reference<T>' class. In other words, some kind of class like a smart-pointer except that the 'Reference' is the only way to access the object to which it refers. I want to prevent 'address-of' and references and use the 'Reference' as a means to manage object life-time.
I do this by writing public static "Create" methods in each class that
return a smart pointer to the new object. All constructors are
private/protected so there is no way of creating the object outside of
the static methods. Consequently there is no direct access to the object
itself (only through the smart pointer), so a reference or pointer to it
cannot be obtained (unless the smart pointer allows it).
Like this:
class SafeObject
{
public:
static MySmartPtr< SafeObject > Create();
private:
SafeObject() {}
// Probably don't need private copy-ctors or copy-assignment
// operators, because you can't access the object directly
// to use them with anyway.
};
Where "MySmartPtr" is your "Reference" class template. You will be able
to take a reference or pointer of MySmartPtr, but not of SafeObject
directly (to the best of my knowledge).
Hope that helps.
-- Pete
Pete Vidler wrote: Tim Clacy wrote: Am I correct in think that you can't re-assign a reference to a different object? If so, what should happen here: Yes.
[snip] { A& a = GetNextA();
a.DoSomeThing(); }
The object "a" only exists within this scope. Once the scope is left it should be destroyed. When the loop re-enters the scope a new object, also called "a", will be created.
Pete,
Hi. So when you loop, this is like leaving a scope then re-entering?
I suppose compiler optimisations might change this behaviour in some unnoticeable way.
Note that I'm not certain about any of this. You could always try it and see what your compiler does.
Does reference 'a' only get assigned first time around the loop and, thereafter, object 'a' gets assigned to the next 'A'... or is 'a' connected to a different 'A' every time around the loop? What about this:
while (1) { { A& a = GetNextA();
a.DoSomeThing(); } } Call me crazy, but isn't that identical to the last bit of code? You're just adding an extra (redundant) scope.
Surely, 'a' would now be different every time around the loop (because the scope of 'a' ends before looping?
Yes, I'm pretty sure they are the same.
Yep, it sounds like they are the same. I wasn't (still not) entirely clear
about life-time of variables/references/objects inside a loop scope. If
variables/references/objects are destroyed and re-constructed every loop
cycle, then my second case is the same as the first. On a related note, is it possible to prevent a reference to a class instance? Similarly, is it possible to prevent the address of an instance from being taken?
What I'm looking for is a way to implement a 'Reference<T>' class. In other words, some kind of class like a smart-pointer except that the 'Reference' is the only way to access the object to which it refers. I want to prevent 'address-of' and references and use the 'Reference' as a means to manage object life-time.
I do this by writing public static "Create" methods in each class that return a smart pointer to the new object. All constructors are private/protected so there is no way of creating the object outside of the static methods. Consequently there is no direct access to the object itself (only through the smart pointer), so a reference or pointer to it cannot be obtained (unless the smart pointer allows it).
Like this:
class SafeObject { public: static MySmartPtr< SafeObject > Create();
private: SafeObject() {}
// Probably don't need private copy-ctors or copy-assignment // operators, because you can't access the object directly // to use them with anyway. };
Where "MySmartPtr" is your "Reference" class template. You will be able to take a reference or pointer of MySmartPtr, but not of SafeObject directly (to the best of my knowledge).
Hope that helps.
Hmm, that's about where I am right now... but all we've done is replaced the
problem of controlling the object life-time with a problem of controlling
the smart-pointer life-time. -- Pete
Ron Natalie wrote: "Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message news:40*********************@dread11.news.tele.dk. ..
while (1) { A& a = GetNextA();
a.DoSomeThing(); }
Since "a" is not declared static, it gets initalized everytime code passes through the block.
while (1) { { A& a = GetNextA();
a.DoSomeThing(); } }
The extra { } have no additional effect here.
On a related note, is it possible to prevent a reference to a class instance? Similarly, is it possible to prevent the address of an instance from being taken?
You can't do anything to prevent a value from being bound to a reference.
Ron,
Hi. Doesn't this mean that there is no automatic way to manage object
life-time (because anyone can just connect a C++ reference to any object)?
You can make taking the address of it difficult, by overloading the unary & operator for the class, but I'm not certain that would be a fool proof way of disabling it entirely. What I'm looking for is a way to implement a 'Reference<T>' class. In other words, some kind of class like a smart-pointer except that the 'Reference' is the only way to access the object to which it refers. I want to prevent 'address-of' and references and use the 'Reference' as a means to manage object life-time.
I'm unclear of what you're really trying to accomplish, however provided you don't specifically provide a way to do with it, a Reference<T> wouldn't be bindable to T&. However such a class would have other problems. Specifically, you can't overload operator (period). .
....hmm, so the long and the short of it is that if you don't mind using '->'
to access objects you can almost acheive automatic object life-time, but if
you want to use '.' you have to use C++ references, which are an
object-life-time management nightmare?
Regards
Tim
Tim Clacy wrote:
[snip] Hi. So when you loop, this is like leaving a scope then re-entering?
Effectively, yes.
[snip]Yes, I'm pretty sure they are the same.
Yep, it sounds like they are the same. I wasn't (still not) entirely clear about life-time of variables/references/objects inside a loop scope. If variables/references/objects are destroyed and re-constructed every loop cycle, then my second case is the same as the first.
Of course, I'm not exactly certain about this. Consider the fact that,
in a "for( int i =... )" loop, the i variable is considered to be inside
the loop's scope. It doesn't get deleted and reconstructed each time,
though.
I'm just confusing myself now. In reality all this is rarely an issue.
If you need a variable in every loop cycle, declare it outside the loop.
[snip] Hmm, that's about where I am right now... but all we've done is replaced the problem of controlling the object life-time with a problem of controlling the smart-pointer life-time.
[snip]
Smart pointers are typically reference counted. If all you really want
is a smart pointer, check out boost::shared_ptr from www.boost.org. I
can highly recommend it (and the rest of that library).
As an aside about shifting the problem onto a separate class, this is a
common technique in C++. The answer to many problems seems to be adding
an extra layer of indirection (so I've heard).
-- Pete
Pete Vidler wrote: Tim Clacy wrote:
[snip]
Hi. So when you loop, this is like leaving a scope then re-entering? Effectively, yes.
[snip]
Yes, I'm pretty sure they are the same.
Yep, it sounds like they are the same. I wasn't (still not) entirely clear about life-time of variables/references/objects inside a loop scope. If variables/references/objects are destroyed and re-constructed every loop cycle, then my second case is the same as the first.
Of course, I'm not exactly certain about this. Consider the fact that, in a "for( int i =... )" loop, the i variable is considered to be inside the loop's scope. It doesn't get deleted and reconstructed each time, though.
There are two nested scopes associated with for loops: an outer scope
for any declaration-definition in the 'for' initializer, and an inner
scope for the loop body. The inner scope may or may not be marked
explicitly with braces but it's always there. The outer scope is entered
once at the beginning of the construct and left once after all
iterations are complete. The inner scope is entered and left on every
iteration.
For while loops, the scope of a declaration in the 'while' condition
contains the scope of the loop body and is entered and left once for
every iteration. It's less important here to make the 'two scopes'
distinction. The same is true of declarations in 'if' conditions.
('switch' too?)
You can depend on this absolutely. Optimization won't change the meaning
of your code. The one small snag is that there are compilers that use
obsolete rules for the scope of declarations in for, while and if
statements. Hopefully it's no longer necessary to think about that.
[...]
Regards,
Buster.
Pete Vidler wrote: Tim Clacy wrote: [snip] Hi. So when you loop, this is like leaving a scope then re-entering? Effectively, yes.
[snip] Yes, I'm pretty sure they are the same.
Yep, it sounds like they are the same. I wasn't (still not) entirely clear about life-time of variables/references/objects inside a loop scope. If variables/references/objects are destroyed and re-constructed every loop cycle, then my second case is the same as the first.
Of course, I'm not exactly certain about this. Consider the fact that, in a "for( int i =... )" loop, the i variable is considered to be inside the loop's scope. It doesn't get deleted and reconstructed each time, though.
I'm just confusing myself now. In reality all this is rarely an issue. If you need a variable in every loop cycle, declare it outside the loop.
[snip] Hmm, that's about where I am right now... but all we've done is replaced the problem of controlling the object life-time with a problem of controlling the smart-pointer life-time. [snip]
Smart pointers are typically reference counted. If all you really want is a smart pointer, check out boost::shared_ptr from www.boost.org. I can highly recommend it (and the rest of that library).
I've have perused Boost (some of the 15MB) and there's some awfully clever
stuff in there. However, what's to stop someone taking a C++ reference to a
smart-pointer (i.e. defeating the purpose)?
As an aside about shifting the problem onto a separate class, this is a common technique in C++. The answer to many problems seems to be adding an extra layer of indirection (so I've heard).
-- Pete
Buster wrote: Pete Vidler wrote:
Tim Clacy wrote: > [snip]
Hi. So when you loop, this is like leaving a scope then re-entering?
Effectively, yes. > [snip]
Yes, I'm pretty sure they are the same.
Yep, it sounds like they are the same. I wasn't (still not) entirely clear about life-time of variables/references/objects inside a loop scope. If variables/references/objects are destroyed and re-constructed every loop cycle, then my second case is the same as the first.
Of course, I'm not exactly certain about this. Consider the fact that, in a "for( int i =... )" loop, the i variable is considered to be inside the loop's scope. It doesn't get deleted and reconstructed each time, though.
There are two nested scopes associated with for loops: an outer scope for any declaration-definition in the 'for' initializer, and an inner scope for the loop body. The inner scope may or may not be marked explicitly with braces but it's always there. The outer scope is entered once at the beginning of the construct and left once after all iterations are complete. The inner scope is entered and left on every iteration.
For while loops, the scope of a declaration in the 'while' condition contains the scope of the loop body and is entered and left once for every iteration. It's less important here to make the 'two scopes' distinction. The same is true of declarations in 'if' conditions. ('switch' too?)
You can depend on this absolutely. Optimization won't change the meaning of your code. The one small snag is that there are compilers that use obsolete rules for the scope of declarations in for, while and if statements. Hopefully it's no longer necessary to think about that.
> [...]
Regards, Buster.
Cheers.
* "Tim Clacy" <no*******@nospamphaseone.nospamdk> schriebt: Hi. Doesn't this mean that there is no automatic way to manage object life-time (because anyone can just connect a C++ reference to any object)?
In theory yes. In practice no. Both because code that does that breaks
the contract, and because you _can_ (although no one does) make it
utterly impractical to obtain a direct reference.
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Tim Clacy wrote:
[snip] I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to a smart-pointer (i.e. defeating the purpose)?
[snip]
Nothing prevents it. It just isn't a problem.
Unless you have a specific situation where it could be a problem?
-- Pete
"Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message
news:40*********************@dread11.news.tele.dk. .. Pete Vidler wrote: Tim Clacy wrote: [snip] Hi. So when you loop, this is like leaving a scope then re-entering? Effectively, yes.
[snip]
Smart pointers are typically reference counted. If all you really want is a smart pointer, check out boost::shared_ptr from www.boost.org. I can highly recommend it (and the rest of that library).
I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to
a smart-pointer (i.e. defeating the purpose)?
How? Can you show a case where it's an issue? A typical usage would be:
struct A
{
...
bool GotMilk()const{ return true; }
};
void somefunction( A& aRef )
{
bool lGood = aRef.GotMilk():
}
void SomeOtherFunction()
{
boost::shared_ptr<A> lAPtr( new A );
...
somefunction( *lAPtr ); // reference valid for the
// duration of somefunction
// indeed for this entire scope
...
} //
Jeff F
Alf P. Steinbach wrote: * "Tim Clacy" <no*******@nospamphaseone.nospamdk> schriebt: Hi. Doesn't this mean that there is no automatic way to manage object life-time (because anyone can just connect a C++ reference to any object)?
In theory yes. In practice no. Both because code that does that breaks the contract, and because you _can_ (although no one does) make it utterly impractical to obtain a direct reference.
Alf,
Hi. How can one make it impractical to obtain a direct reference to an
object; others are saying that you can't do that?
Tim
Pete Vidler wrote: Tim Clacy wrote: [snip] I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to a smart-pointer (i.e. defeating the purpose)? [snip]
Nothing prevents it. It just isn't a problem.
....hmm, don't you think robust object life-time management is just about the
most important thing to get right to help ensure a robust, quality product?
My experience is that if something is fragile, sooner or later, it will
break... but perhaps I've just been unlucky?
Unless you have a specific situation where it could be a problem?
-- Pete
Jeff Flinn wrote: "Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message news:40*********************@dread11.news.tele.dk. .. Pete Vidler wrote: Tim Clacy wrote: [snip] Hi. So when you loop, this is like leaving a scope then re-entering?
Effectively, yes.
[snip] Smart pointers are typically reference counted. If all you really want is a smart pointer, check out boost::shared_ptr from www.boost.org. I can highly recommend it (and the rest of that library). I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to a smart-pointer (i.e. defeating the purpose)?
How? Can you show a case where it's an issue? A typical usage would be:
struct A { ...
bool GotMilk()const{ return true; } };
void somefunction( A& aRef ) { bool lGood = aRef.GotMilk(): }
void SomeOtherFunction() { boost::shared_ptr<A> lAPtr( new A );
...
somefunction( *lAPtr ); // reference valid for the // duration of somefunction // indeed for this entire scope
What if somefunction assigns a static or class member to that reference...
or copies it to another thread? } //
Jeff F
Tim Clacy wrote:
[snip] Nothing prevents it. It just isn't a problem.
...hmm, don't you think robust object life-time management is just about the most important thing to get right to help ensure a robust, quality product? My experience is that if something is fragile, sooner or later, it will break... but perhaps I've just been unlucky?
[snip]
Yes, but using a smart pointer is just about as robust as it gets. You
still haven't explained how it isn't robust -- there's nothing wrong
with taking a reference to the smart pointer that I can see. So long as
you don't mess with raw pointers your app will be perfectly robust.
The only problem would be if you could assing a temporary object to a
reference, but I'm pretty sure the standard forbids it. You can assign
temporaries to const references, but then the lifetime of the temporary
is guaranteed to be at least as long as the lifetime of the const
reference (I believe).
-- Pete
Tim Clacy wrote:
[snip] What if somefunction assigns a static or class member to that reference... or copies it to another thread?
[snip]
In the case of a programmer assigning static members to references, the
fool deserves everything he gets. You can protect programmers from
themselves only so far.
In the given example you cannot reassign a reference. It just isn't
legal C++. You can alter the object that the reference is of, in ways
determined by the interface of its class (providing it's a non-const
reference), but that's about it.
-- Pete
"Pete Vidler" <pv*****@mailblocks.com> wrote in message
news:ba***************@newsfe1-gui.server.ntli.net... Tim Clacy wrote: [snip]Nothing prevents it. It just isn't a problem. ...hmm, don't you think robust object life-time management is just about
the most important thing to get right to help ensure a robust, quality
product? My experience is that if something is fragile, sooner or later, it will break... but perhaps I've just been unlucky? [snip]
Yes, but using a smart pointer is just about as robust as it gets. You still haven't explained how it isn't robust -- there's nothing wrong with taking a reference to the smart pointer that I can see. So long as you don't mess with raw pointers your app will be perfectly robust.
I'm almost convinced... provided that it is possible to ensure that only the
smart pointer can do the creation of the object and that it's not possible
to 'new' smart pointers (so the life-time of the smart-pointer is under
control) and it's not possible to take the address of smart pointers. That
should all be acheivable shouldn't it?
I think I'll spend the weekend studying Boost's smart pointer.
Cheers
The only problem would be if you could assing a temporary object to a reference, but I'm pretty sure the standard forbids it. You can assign temporaries to const references, but then the lifetime of the temporary is guaranteed to be at least as long as the lifetime of the const reference (I believe).
-- Pete
* "Tim Clacy" <no*******@nospamphaseone.nospamdk> schriebt: How can one make it impractical to obtain a direct reference to an object
This was discussed in
<url:
http://www.google.com/groups?threadm=c0aur7%2414gog5%241%40ID-14036.news.uni-berlin.de>
Summary of proposed solutions in the context of preventing deletion via
a raw pointer obtained from a smart-pointer class:
Andrei Alexandrescu, Thomas Mang, Steve Dewhurst:
Let operator-> return a proxy (and Andrei, of course, further proposed
using a recursive template to generate a proxy to proxy to proxy..., say
to 100 levels, to really make it hard for client code to get the address).
Paavo Helde:
If you own the implementation of the class A that the smart pointer
encapsulates, let its destructor be protected and let the smart
pointer's operator-> return a pointer to a derived class instance.
Niklas Borson:
Let the smart pointer be a wrapper class with one wrapper function
for each function of the wrapped class, instead of using operator->.
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Tim Clacy wrote:
[snip] I'm almost convinced... provided that it is possible to ensure that only the smart pointer can do the creation of the object and that it's not possible to 'new' smart pointers (so the life-time of the smart-pointer is under control) and it's not possible to take the address of smart pointers. That should all be acheivable shouldn't it?
[snip]
The basics are straight from the FAQ:
class SafeClass
{
public:
typedef boost::shared_ptr< SafeClass > Ptr;
// Might need a static_cast here, I don't remember exactly.
Ptr Create() { return new SafeClass; }
private:
SafeClass() { ... }
};
// This should be the only way to create a SafeClass object:
SafeClass::Ptr safeClass1 = SafeClass::Create();
This meets my top two criteria -- safe and readable.
In the thread "Base class method that returns a pointer to a derived
class?" on this newsgroup I've detailed a technique for extending this
to a hierarchy (from Maxim Yegorushkin on comp.lang.c++.moderated).
-- Pete
Pete Vidler wrote:
[snip] class SafeClass { public: typedef boost::shared_ptr< SafeClass > Ptr;
// Might need a static_cast here, I don't remember exactly. Ptr Create() { return new SafeClass; }
That Create method was meant to be static, obviously.
private: SafeClass() { ... } };
// This should be the only way to create a SafeClass object: SafeClass::Ptr safeClass1 = SafeClass::Create();
-- Pete
Pete Vidler wrote:
[snip] class SafeClass { public: typedef boost::shared_ptr< SafeClass > Ptr;
// Might need a static_cast here, I don't remember exactly. Ptr Create() { return new SafeClass; }
That Create method was meant to be static, obviously.
private: SafeClass() { ... } };
// This should be the only way to create a SafeClass object: SafeClass::Ptr safeClass1 = SafeClass::Create();
-- Pete
"Pete Vidler" <pv*****@mailblocks.com> wrote in message
news:gM*************@newsfe5-gui.server.ntli.net... Pete Vidler wrote: [snip] class SafeClass { public: typedef boost::shared_ptr< SafeClass > Ptr;
// Might need a static_cast here, I don't remember exactly. Ptr Create() { return new SafeClass; }
That Create method was meant to be static, obviously.
private: SafeClass() { ... } };
// This should be the only way to create a SafeClass object: SafeClass::Ptr safeClass1 = SafeClass::Create();
-- Pete
Don't we have an even worse issue here; what if someone makes a reference to
the returned temporary instead of copying it:
SafeClass::Ptr& safeClass1 = SafeClass::Create();
Now the instance of SafeClass is a bona-fide memory leak.
"Pete Vidler" <pv*****@mailblocks.com> wrote in message
news:gM*************@newsfe5-gui.server.ntli.net... Pete Vidler wrote: [snip] class SafeClass { public: typedef boost::shared_ptr< SafeClass > Ptr;
// Might need a static_cast here, I don't remember exactly. Ptr Create() { return new SafeClass; }
That Create method was meant to be static, obviously.
private: SafeClass() { ... } };
// This should be the only way to create a SafeClass object: SafeClass::Ptr safeClass1 = SafeClass::Create();
-- Pete
Don't we have an even worse issue here; what if someone makes a reference to
the returned temporary instead of copying it:
SafeClass::Ptr& safeClass1 = SafeClass::Create();
Now the instance of SafeClass is a bona-fide memory leak.
"Pete Vidler" <pv*****@mailblocks.com> wrote in message
news:bfgbc.204$%m5.81@newsfe1-win... Tim Clacy wrote: [snip] What if somefunction assigns a static or class member to that
reference... or copies it to another thread? [snip]
In the case of a programmer assigning static members to references, the fool deserves everything he gets. You can protect programmers from themselves only so far.
In the given example you cannot reassign a reference. It just isn't legal C++. You can alter the object that the reference is of, in ways determined by the interface of its class (providing it's a non-const reference), but that's about it.
-- Pete
But the big problem, surely, is that when the reference goes out of scope,
the destructor of the object to which it refers is not called and we have a
lingering object. It seems much easier to make reference to instances than
to ensure that those instances are cleaned-up when its referees expire.
"Pete Vidler" <pv*****@mailblocks.com> wrote in message
news:bfgbc.204$%m5.81@newsfe1-win... Tim Clacy wrote: [snip] What if somefunction assigns a static or class member to that
reference... or copies it to another thread? [snip]
In the case of a programmer assigning static members to references, the fool deserves everything he gets. You can protect programmers from themselves only so far.
In the given example you cannot reassign a reference. It just isn't legal C++. You can alter the object that the reference is of, in ways determined by the interface of its class (providing it's a non-const reference), but that's about it.
-- Pete
But the big problem, surely, is that when the reference goes out of scope,
the destructor of the object to which it refers is not called and we have a
lingering object. It seems much easier to make reference to instances than
to ensure that those instances are cleaned-up when its referees expire.
Tim wrote:
[snip] Don't we have an even worse issue here; what if someone makes a reference to the returned temporary instead of copying it:
SafeClass::Ptr& safeClass1 = SafeClass::Create();
Now the instance of SafeClass is a bona-fide memory leak.
[snip]
No it isn't. The standard forbids assigning a temporary to a non-const
reference. It won't even compile (with a half decent compiler).
If you used a const-reference, the object is guaranteed to survive at
least as long as the const-reference.
Besides, that isn't a memory leak even if it was allowed. The smart
pointer will always free the memory, it's just that the reference would
then be invalid. But it can't happen, so it doesn't matter.
-- Pete
Tim wrote:
[snip] Don't we have an even worse issue here; what if someone makes a reference to the returned temporary instead of copying it:
SafeClass::Ptr& safeClass1 = SafeClass::Create();
Now the instance of SafeClass is a bona-fide memory leak.
[snip]
No it isn't. The standard forbids assigning a temporary to a non-const
reference. It won't even compile (with a half decent compiler).
If you used a const-reference, the object is guaranteed to survive at
least as long as the const-reference.
Besides, that isn't a memory leak even if it was allowed. The smart
pointer will always free the memory, it's just that the reference would
then be invalid. But it can't happen, so it doesn't matter.
-- Pete
"Tim Clacy" wrote: Pete Vidler wrote: Tim Clacy wrote: I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to a smart-pointer (i.e. defeating the purpose)? Nothing prevents it. It just isn't a problem.
...hmm, don't you think robust object life-time management is just about the most important thing to get right to help ensure a robust, quality product?
No! I'm firmly on the Murphy side (and you seem to be on the
Machiavelli side): I think the idea is to make sure the users of your
library don't screw up accidentally, but not to try and prevent them
screwing up on purpose. No matter what measures you take, there
will always be a way to get around them if someone is hell-bent on
doing so.
My experience is that if something is fragile, sooner or later, it will break... but perhaps I've just been unlucky?
What does 'pointer' have to do with 'fragile' ?
If someone creates and deletes your objects, good on them. You
don't have to try and prevent people from forgetting to free a
pointer, for example.
IMHO, adding more complexity to your class to guard against nasty
people, is just making it more fragile.
"Tim Clacy" wrote: Pete Vidler wrote: Tim Clacy wrote: I've have perused Boost (some of the 15MB) and there's some awfully clever stuff in there. However, what's to stop someone taking a C++ reference to a smart-pointer (i.e. defeating the purpose)? Nothing prevents it. It just isn't a problem.
...hmm, don't you think robust object life-time management is just about the most important thing to get right to help ensure a robust, quality product?
No! I'm firmly on the Murphy side (and you seem to be on the
Machiavelli side): I think the idea is to make sure the users of your
library don't screw up accidentally, but not to try and prevent them
screwing up on purpose. No matter what measures you take, there
will always be a way to get around them if someone is hell-bent on
doing so.
My experience is that if something is fragile, sooner or later, it will break... but perhaps I've just been unlucky?
What does 'pointer' have to do with 'fragile' ?
If someone creates and deletes your objects, good on them. You
don't have to try and prevent people from forgetting to free a
pointer, for example.
IMHO, adding more complexity to your class to guard against nasty
people, is just making it more fragile. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Tim Clacy |
last post by:
Am I correct in think that you can't re-assign a reference to a different
object? If so, what should happen here:
struct A
{
DoSomeThing();
};
A& GetNextA();
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
| | |