![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible <voi### [at] dev null> wrote:
> Warp wrote:
> > Invisible <voi### [at] dev null> wrote:
> >> Copy...constructor...? x_x
> >
> > Usually you don't need copy constructors unless you have pointers as
> > member variables of your class and you explicitly allocate memory to
> > them with 'new'. But we don't do that, do we? ;)
> Heh. I get the impression that most of the stuff I'm reading about now
> is stuff that "you won't normally need". ;-)
It's not like you don't need copy constructors (and copy assignment).
It's just that a beginner doesn't usually need them. When you start needing
copy constructors, your code will be a bit more advanced.
> (E.g., apparently you can overload the "->" operator... GAH! >_< OK, I
> am *so* not trying that out!)
You can overload almost any operator, including 'new' (it's considered
an operator in C++) and the prefix-&.
I think the only operator you can't overload is the dot operator.
> Anyway, the main reason I haven't written a Third C++ Program yet is
> that I'm trying to think of something I actually want to write that's
> implementable without automatic memory management...
Hmm, is that sentence correct? Everything is implementable without
automatic memory management. Perhaps you meant something else?-)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> Heh. I get the impression that most of the stuff I'm reading about now
>> is stuff that "you won't normally need". ;-)
>
> It's not like you don't need copy constructors (and copy assignment).
> It's just that a beginner doesn't usually need them. When you start needing
> copy constructors, your code will be a bit more advanced.
Well, yeah. And *I* am unlikely to be writing anything "advanced" any
time soon! ;-)
>> (E.g., apparently you can overload the "->" operator... GAH! >_< OK, I
>> am *so* not trying that out!)
>
> You can overload almost any operator, including 'new' (it's considered
> an operator in C++) and the prefix-&.
>
> I think the only operator you can't overload is the dot operator.
And .* (apparently).
Also, unlike Haskell, you apparently can't make up new operators of your
own, just overload the ones that already exist.
>> Anyway, the main reason I haven't written a Third C++ Program yet is
>> that I'm trying to think of something I actually want to write that's
>> implementable without automatic memory management...
>
> Hmm, is that sentence correct? Everything is implementable without
> automatic memory management. Perhaps you meant something else?-)
Well, yeah, but it's a touch harder to implement heap-allocated data in
such a way that your program doesn't leak like a sieve. ;-)
[I'm actually surprised that using std::vector doesn't do this already...]
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible <voi### [at] dev null> wrote:
> Also, unlike Haskell, you apparently can't make up new operators of your
> own, just overload the ones that already exist.
Aren't C++ compilers already stressed enough? Think about all the problems
they would have with user-defined operators, with their own precedence
rules, ambiguous situations, etc... :P
> Well, yeah, but it's a touch harder to implement heap-allocated data in
> such a way that your program doesn't leak like a sieve. ;-)
You usually use the STL data containers for dynamically allocated
memory, and if what you need is to allocate a single object, you can
use a smart pointer (I posted in the other group an URL to one smart
pointer implementation I have made).
> [I'm actually surprised that using std::vector doesn't do this already...]
Doesn't do what?
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> Also, unlike Haskell, you apparently can't make up new operators of your
>> own, just overload the ones that already exist.
>
> Aren't C++ compilers already stressed enough? Think about all the problems
> they would have with user-defined operators, with their own precedence
> rules, ambiguous situations, etc... :P
Heh, yeah... I can see that. ;-)
>> Well, yeah, but it's a touch harder to implement heap-allocated data in
>> such a way that your program doesn't leak like a sieve. ;-)
>
> You usually use the STL data containers for dynamically allocated
> memory, and if what you need is to allocate a single object, you can
> use a smart pointer.
Fair enough.
>> [I'm actually surprised that using std::vector doesn't do this already...]
>
> Doesn't do what?
Leak like a sieve! ;-)
I've never actually seen a programming environment with manual memory
management *and* dynamically resizable collections. The two are usually
muturally exclusive.
Then again, I'm not really sure what the story is if you try to put
user-defined data types into a vector...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
>
> (E.g., apparently you can overload the "->" operator... GAH! >_< OK, I
> am *so* not trying that out!)
>
Useful for the "Smart Pointer" pattern. The autogen stuff for COM uses
these a lot.
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible <voi### [at] dev null> wrote:
> >> [I'm actually surprised that using std::vector doesn't do this already...]
> >
> > Doesn't do what?
> Leak like a sieve! ;-)
The class constructors, assignment and destructor help in automatizing
the internal memory management of the vector.
You can write your own dynamic data container as a class in the exact
same way as std::vector and the other STL containers, which will be safe
and will automatically manage its memory.
And not only memory. There are also other resources which can be
automatically managed with classes. Consider this:
void foo()
{
std::ofstream os("outfile.txt");
os << "Hello\n";
bar();
os << "there.\n";
}
Note that nowhere is the file actually explicitly *closed*. However,
no open file handles are leaked because it gets closed automatically
because the std::ofstream class handles this resource.
This is even so even if the function is exited abnormally. For example,
assume that the bar() call throws an exception. If that happens, the
function will be exited immediately (before the "there.\n" string is
written to the file). This is "unexpected" and we didn't take that
possibility into account. However, it doesn't matter: The file will
still be closed and thus no resource leak happens.
Unless I'm completely mistaken, this is not something you can achieve
in Java. (In Java you have to close files explicitly and catch all
possible exceptions which might otherwise bypass that closing.)
> I've never actually seen a programming environment with manual memory
> management *and* dynamically resizable collections. The two are usually
> muturally exclusive.
Well, it's not like *all* resources in C++ are managed manually.
More precisely, stack-allocated objects are managed automatically. Which
is exactly the reason why automatic management heap-allocated objects
becomes possible through these stack-allocated objects.
> Then again, I'm not really sure what the story is if you try to put
> user-defined data types into a vector...
If the user-defined type doesn't allocate memory in itself, or if it
does but manages it properly, there shouldn't be any problems.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Mike Raiford <"m[raiford]!at"@gmail.com> wrote:
> Invisible wrote:
> > (E.g., apparently you can overload the "->" operator... GAH! >_< OK, I
> > am *so* not trying that out!)
> >
> Useful for the "Smart Pointer" pattern. The autogen stuff for COM uses
> these a lot.
Also used with iterators. (An iterator is an object which behaves
like a pointer.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> The class constructors, assignment and destructor help in automatizing
> the internal memory management of the vector.
>
> You can write your own dynamic data container as a class in the exact
> same way as std::vector and the other STL containers, which will be safe
> and will automatically manage its memory.
But presumable you'd need to know what you're doing first. ;-)
> And not only memory. There are also other resources which can be
> automatically managed with classes.
Mmm, that's nice.
> Unless I'm completely mistaken, this is not something you can achieve
> in Java. (In Java you have to close files explicitly and catch all
> possible exceptions which might otherwise bypass that closing.)
Actually, for reasons beyond my comprehension, if a Haskell program
halts abnormally, all files are closed, but not necessarily *flushed*.
Like, WTF? *Why?* Anyway, basically you have to write some code to catch
the exception and close the file before rethrowing it. It's an extra 3
lines of code, but you still have to remember to type them...
>> I've never actually seen a programming environment with manual memory
>> management *and* dynamically resizable collections. The two are usually
>> muturally exclusive.
>
> Well, it's not like *all* resources in C++ are managed manually.
> More precisely, stack-allocated objects are managed automatically. Which
> is exactly the reason why automatic management heap-allocated objects
> becomes possible through these stack-allocated objects.
Indeed. I've not seen this in any other OO language.
>> Then again, I'm not really sure what the story is if you try to put
>> user-defined data types into a vector...
>
> If the user-defined type doesn't allocate memory in itself, or if it
> does but manages it properly, there shouldn't be any problems.
Sounds good to me! ;-)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
> Looks like it would only be useful for some pretty obscure situations...
Really? They're useful all the time in C#. Like, every time you have a
callback function you register with the GUI, or every time in Java where
you'd have to create an anonymous inner class or something. Pointers to
members are the OO mechanism corresponding to closures.
You have a window representing an object. You want to be notified
whenever the mouse moves over the window. How do you tell the window
manager that?
--
Darren New / San Diego, CA, USA (PST)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Unless I'm completely mistaken, this is not something you can achieve
> in Java. (In Java you have to close files explicitly and catch all
> possible exceptions which might otherwise bypass that closing.)
The destructor will close the file when the GC collects the object, but
that might be several seconds later. And it might not run if you exit
the program before the GC runs, but that's true of C++ also. So it's not
quite as nicely deterministic, but it still happens eventually.
--
Darren New / San Diego, CA, USA (PST)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |