A call doesn't really have an owner. I guess you could call the
initiating party the owner, but he won't necessarily be around
when the call needs to be terminated. One of the basic
characteristics of a call in modern systems is that once
established, it has a life independent of the establishing
party.
That does not follow. Often, in fact, more objects lead to
less complexity. You obviously don't stick all your code into
a single, unstructured object, so I'm not sure why you would
make this claim.
In this case, the added object doesn't provide any additional
functionality; it just adds complexity, for no reason.
Its owner, and so on, up to the top level of the program. If
you're ever built a GUI, you know that there are a few
top-level entities (usually frames), and that every other
widget falls into a hierarchy, with a clear ownership tree.
Yes, and I also know that in most cases, it isn't the *owner*
who destroys the various objects, at least at specific levels;
if the frame is destructed, of course, it may destruct
everything below it, but if you swap specific panes in and out,
the frame doesn't normally get involved.
This kind of organization isn't GUI-specific, nor in fact does
any other kind of organization make much sense for
general-purpose programming.
I'm sorry, but in practice, I find very few cases in general
programming where "ownership" makes sense. It's sometimes
introduced artificially into C++, because C++ lacks a garbage
collector, and it does make sense for some special low level
objects, like mutex locks (but such objects are usually local
variables, so the issue doesn't really arise), but most entity
objects don't logically have an owner, and forcing them to have
one distorts the design.
The function call mechanism, for example, forms such a tree:
Each function-call is made by, and outlived by, some other,
parent call.
Yes, but if you're dynamically allocating objects, instead of
using local variables, it's precisely because the function call
model of nested lifetimes doesn't apply.
[...]
You're using call to mean two different things there: The
physical process represented by the software object, and the
object itself.
It's an entity object; it models a non-software entity in the
actual application.
I didn't realize we were this far apart. This is a topic for
a book, not a usenet post.
Yes, but to date, I've yet to find any book arguing your point
of view. The major references (e.g. Booch) tend to agree with
me.
Because auto objects are effectively owned by their stack
frames, which aren't objects.
That could be argued as well
. In C++, for historical
reasons, stack frames aren't treated as objects, but but lambda
comes very close to eliminating the differences in some cases.
Static objects are owned by the larger run-time environment,
to the extent they have ownership at all. There's always a
base case to ownership.
Yes. The OS owns your program, and you (or your employer) own
the machine on which it runs.
So? I think you're forcing the issue---quite obviously, the
sense of "own" is different when I say you own the machine. If
you diffuse the meaning this much, yes, every object has an
owner. Or several. Or at times none. But if you diffuse the
sense of "own" this much, it has nothing to do with lifetime, or
who should call delete.
Thanks for keeping this erudite.
As long as you can't give a reason for it, it's prejudice. To
date, you've made a lot of pronouncements as to how things
"should" be, without giving any reasons as to why they should
be. And what you claim "should" be goes against concrete
experience.
The point of dynamic allocation is that you don't know a
priori how many of something you'll need, or else that it may
not fit in the stack. That's why we have resizable
containers. If a function needs to return something that will
outlive the call, that something should be obtained from a
factory that lives at a higher level of abstraction. This is
the canonical case of dependency inversion. Parameterizing
the code with a specific factory is the canonical case for
dependency injection.
Adding factories for no other reason than to ensure that the
creating object outlives its creator is just added verbosity.
What's the difference between:
return XxxFactory::instance().createObject() ;
and
return new Xxx ;
or between:
XxxFactory::instance().deleteMe() ;
and
delete this ;
? Other than you've introduced added verbosity, and additional
code which needs maintaining.