SmartPointer & Inheritance & Explicit Constructors

C

coder_lol

Thanks everyone again for contributing to helping me clear C++
confusions. I did some serious reading on copy constructors and
assignments and I think I've got a good handle on the memory stuff.

Well, I came across Scott Meyer's SmartPtr example from some 10 years
ago. I like the template member function for type conversion to solve
inheritance issues.

On MSVS 2003, I get the below error, if I declare the constructor
SmartPtr(T* realPtr = 0); as explicit, ie.

explicit SmartPtr(T* realPtr = 0);


SmartPtr.h(33): error C2520: SmartPtr<T>::SmartPtr: no non-explicit
constructor available for implicit conversion
with
[
T=Object
]
and
[
T=Object
]


I think of explicit as an "insurance" against silly mistakes. Is
there a way to solve the issue and keep explicit?

Thanks...

=== Scott Meyer's===
template<class T> // template class for smart
class SmartPtr { // pointers-to-T objects
public:
SmartPtr(T* realPtr = 0);
T* operator->() const;
T& operator*() const;
template<class newType> // template function for
operator SmartPtr<newType>() // implicit conversion ops.
{
return SmartPtr<newType>(pointee);
}
 
J

Jon Harrop

Well, I came across Scott Meyer's SmartPtr example from some 10 years
ago. I like the template member function for type conversion to solve
inheritance issues.

As smart pointers are a rudimentary precursor of garbage collection, you
might consider a full-blown garbage collector or a garbage collected
language. There is really no need to battle "inheritance issues" any more.
 
J

James Kanze

As smart pointers are a rudimentary precursor of garbage collection, you
might consider a full-blown garbage collector or a garbage collected
language.

It depends on what the smart pointers are used for. I normally
use the Boehm collector for new projects, but I still use smart
pointers in some cases: to manage locks, for example, or to
manage ownership between threads. In the past, I've also used
them for simplified transaction management, and manually managed
object paging (keeping most of the objects physically on disk,
and not in memory).

Obviously, it's stupid not to use the Boehm collector when you
can, but just as obviously, it's not a silver bullet, and can
only replace those smart pointers which were being used
exclusively for memory management.
 
G

Gianni Mariani

James Kanze wrote:
....
Obviously, it's stupid not to use the Boehm collector when you
can,

I have found that using smart pointers is almost all that is needed to
develop a leak free application. The circular pointers issue is
normally very easy to design around.
 
J

James Kanze

James Kanze wrote:
I have found that using smart pointers is almost all that is needed to
develop a leak free application. The circular pointers issue is
normally very easy to design around.

If you can't implement an application that works without garbage
collection, you won't be able to implement one with. In the old
days, I've even implemented complex applications fully in
assembler.

On the other hand, it's a lot less work if you have the
appropriate tools. Garbage collection reduces the amount of
code I have to write, and so reduces how much it costs to
develop the working application. Given that the Boehm collector
is readily available and easy to use, it would be stupid not to
use it when you can. (I don't use assembler today, either,
unless I have to.)
 
C

coder_lol

Using a refcount smart pointer, can you show me an actual code example
of when a circular dependency is created? Yeah, I figure A->B and B-
A, but I'd appreciate if you could share actual code samples.

Thanks,
 
C

coder_lol

How well does BOEHM work in an embedded environment? I have to port
substantial amount of J2ME applications to another C/C++ embedded
environment. Based on my study, I figure that RefCount smart pointers
and proper use of assignment operator and copy constructor will
essentially give me the a pseudo Java "reference" / garbage collection
programming model.

I scanned BOEHM briefly and it is very interesting that you don't need
to modify your code to employ it, but how does it work in an embedded
environment esp. single-threaded embedded env.

Thanks...
 
G

Gianni Mariani

James Kanze wrote:
.... Given that the Boehm collector
is readily available and easy to use, it would be stupid not to
use it ...

Are you meaning to suggest that the Boehm collector will perform without
any issues perfectly every time, no side effects, just peachy even ?
 
G

Gianni Mariani

Using a refcount smart pointer, can you show me an actual code example
of when a circular dependency is created? Yeah, I figure A->B and B->A,
but I'd appreciate if you could share actual code samples.

Networks usually are hard to implement because any object can point to
any other object. One of my first applications using reference counted
objects, I had identified that this might happen (seldom but did happen)
and a secondary method to clean up those objects were needed. Objects
were given a lifetime handle and when it was determined that the life of
all the objects of that network were done with, regardless of the
reference count, all the objects removed themselves from the network
which then automatically deleted themselves because their reference
count went to zero. Today I'd consider using a garbage collector on
code like that.

Most of my applications since then have not been anywhere near as
complex from a lifetime management point of view and judicious use of
reference counting smart pointers eliminated all (yes - all) issues with
resource leaks. The most recent project I worked on came to life with
no memory leaks (a few handle leaks tho) to the astonishment of many of
the old timer engrs.

Garbage collection is not free, it can be somewhat expensive in compute
resources. For short lived applications, it may be better since it is
likely that the collector never runs. For long running applications, it
can introduce unwanted timing issues.

I have no used the Bohem collector, I hope it becomes a standard feature
personally but I also would not support it becoming a mandatory
requirement for all C++ code.
 
J

Jon Harrop

I scanned BOEHM briefly and it is very interesting that you don't need
to modify your code to employ it

You do need to modify your code if you hide pointers (e.g. as ints). Also,
Boehm is unreliable or "conservative". You're much better off using a real
GC.
 
J

James Kanze

How well does BOEHM work in an embedded environment? I have
to port substantial amount of J2ME applications to another
C/C++ embedded environment. Based on my study, I figure that
RefCount smart pointers and proper use of assignment operator
and copy constructor will essentially give me the a pseudo
Java "reference" / garbage collection programming model.

It depends really on the embedded environment. I'm tempted to
say that it works about as well as ref. counted smart
pointers:). But that's probably because all of my experience
in embedded environments has been hard real time applications,
where no dynamic memory allocation was allowed.

Generally, the Boehm collector will require more memory than
manually allocating and deleting. (In most cases, to judge from
my experience, it will also be a little bit faster.)
I scanned BOEHM briefly and it is very interesting that you
don't need to modify your code to employ it, but how does it
work in an embedded environment esp. single-threaded embedded
env.

I suspect that there are two elements that you have to consider:
it typically does require more memory than manual allocation,
and if memory is tight, it might not be the ideal solution. And
at least in the configurations I've used, it doesn't give any
hard real time guarantees (but then, neither does malloc/free,
and I've had serious problems with the latency of malloc in the
past).

One final consideration: the Boehm collector has been ported to
Windows and to most mainstream Unix environments. If you're
target machine isn't one of those (and watch out for modified
versions of Linux), then you may have to port it yourself. I've
never done that, but I can imagine that it's not necessarily
trivial.
 
J

James Kanze

James Kanze wrote:
... Given that the Boehm collector
Are you meaning to suggest that the Boehm collector will
perform without any issues perfectly every time, no side
effects, just peachy even ?

It's not a silver bullet, if that's what you're asking. On
typical systems to which it has been ported (I've used it under
Solaris and Linux), it works without problems, resulting in
faster programs at less work from the programmer.

I'm not sure what you mean by "side effects", however.
 
J

James Kanze

Using a refcount smart pointer, can you show me an actual code
example of when a circular dependency is created? Yeah, I
figure A->B and B-> A, but I'd appreciate if you could share
actual code samples.

A dual linked list. Many tree structures. Any time
bidirectional navigation is required, in fact.
 
J

James Kanze

Most of my applications since then have not been anywhere near as
complex from a lifetime management point of view and judicious use of
reference counting smart pointers eliminated all (yes - all) issues with
resource leaks. The most recent project I worked on came to life with
no memory leaks (a few handle leaks tho) to the astonishment of many of
the old timer engrs.

I'd say that this is actually fairly typical. The key word
above being "judicious". With garbage collection, there are
many cases where you don't even have to think about it. Doing
it right without garbage collection is far from impossible, but
doing it right with garbage collection is less work.
Garbage collection is not free, it can be somewhat expensive
in compute resources.

Which explains why programs using garbage collection are
typically faster than those without.
For short lived applications, it may be better since it is
likely that the collector never runs. For long running
applications, it can introduce unwanted timing issues.

That depends on the collector used. There are collectors which
give hard real-time guarantees (which malloc and free typically
don't); I've never needed one, however, so I don't know much
more than that they exist. A good incremental collector,
however, will generally not cause any problems, and it's usually
easier to tune the application (by explicitly collecting when
the system is otherwise idle, for example) with a collector than
with manual management. Of course, this depends at least
partially on memory use patterns; programs with lots of small,
short-lived allocations generally run faster with the garbage
collector; programs with very few, very long lived allocations
run slower.

The main cost of the Boehm collector is in total memory usage,
and at least at times, in locality.
I have no used the Bohem collector, I hope it becomes a standard feature
personally but I also would not support it becoming a mandatory
requirement for all C++ code.

There's no proposal for it to be mandatory; it's well recognized
that there are times when it isn't appropriate.
 
C

Chris Thomasson

[...]
Which explains why programs using garbage collection are
typically faster than those without.

What type of garbage collection are you talking about? Some of the methods
used to actually implement most types of "general purpose" garbage
collection are overkill and can have an overall negative effect on
scalability and performance in general. IMHO, C++ simply does not need a GC.
 
C

Chris Thomasson

It depends really on the embedded environment. I'm tempted to
say that it works about as well as ref. counted smart
pointers:).

[...]

I feel the need to point out the fact that you cannot use something like
Boost shared_ptr to implement Java References. Your going to have to use
some sort of PDR scheme instead:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/82376b7295e6ce1a
(origin of term 'PDR'...)


Any solution is going to have to have strong thread-safety characteristics:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/e5167941d32340c6/
(difference between basic and normal thread-safety...)


You certainly do not need a full-blown GC to implement Java References in
C++. For instance, you could use full-blown atomic reference counting to
implement something just like Java References in C++:

http://appcore.home.comcast.net/vzoom/refcount/

http://atomic-ptr-plus.sourceforge.net/



Any thoughts?
 
C

Chris Thomasson

Chris Thomasson said:
[...]
Which explains why programs using garbage collection are
typically faster than those without.

What type of garbage collection are you talking about? Some of the methods
used to actually implement most types of "general purpose" garbage
collection are overkill
[...]

Well, I guess it would be nice for C++ to offer a "Proxy" Garbage Collector
scheme... That would not be overkill IMO because a proxy garbage collector
can actually be implemented with virtually zero-overheads:

http://appcore.home.comcast.net/vzoom/round-1.pdf
(section 1.1)

http://appcore.home.comcast.net/vzoom/round-2.pdf
(section 1.2)
 
B

Bo Persson

Chris Thomasson wrote:
:: ::
:: [...]
::
:::: Garbage collection is not free, it can be somewhat expensive
:::: in compute resources.
::
::: Which explains why programs using garbage collection are
::: typically faster than those without.
::
:: What type of garbage collection are you talking about? Some of the
:: methods used to actually implement most types of "general purpose"
:: garbage collection are overkill and can have an overall negative
:: effect on scalability and performance in general. IMHO, C++ simply
:: does not need a GC.

Using GC saves on allocation and management. Skip your smart pointers
and reference counting, and you save on both execution time and
programming effort.

If the collector isn't run often (or at all, for typical benchmarks!),
it can be a net saving.


Bo Persson
 
C

Chris Thomasson

Bo Persson said:
Chris Thomasson wrote:
:: ::
:: [...]
::
:::: Garbage collection is not free, it can be somewhat expensive
:::: in compute resources.
::
::: Which explains why programs using garbage collection are
::: typically faster than those without.
::
:: What type of garbage collection are you talking about? Some of the
:: methods used to actually implement most types of "general purpose"
:: garbage collection are overkill and can have an overall negative
:: effect on scalability and performance in general. IMHO, C++ simply
:: does not need a GC.

Using GC saves on allocation

What does a general-purpose GC save on allocation in general when compared
to a state-of-the-art memory allocator algorithm:

http://groups.google.com/group/comp.arch/browse_frm/thread/24c40d42a04ee855


and management.

Well, yes I agree that GC makes it so a programmer does not really "need" to
hold a firm understanding of the fact that freeing any memory that is not in
a persistent quiescent state is a very, very bad practice...


Skip your smart pointers and reference counting, and you save on both
execution time

This is simply not true in all cases. I can come up with several scaleable
memory management techniques that a traditional GC cannot compete with.
Here's a question: Can a general-purpose GC guarantee that threads will
never be interrupted by it during their entire lifetimes? I know of
special-purpose GC algorithms that can make this guarantee, however, I can't
think of a general-purpose GC one than can...


and programming effort.

Well, yes... But heck, doesn't that take all the fun out of programming?

:^)


Anyway, I am still holding my opinion that C++ Standard should not force a
GC into the mix...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top