Re: Do I need a singleton here? Or can I use std::move
"James Kanze" <james.kanze@gmail.com> wrote in message
news:207fb1dd-8d1d-4aa2-8b10-929d82f32e87@c20g2000yqj.googlegroups.com...
On Oct 20, 12:26 am, "Jim Langston" <tazmas...@rocketmail.com> wrote:
"Jorgen Grahn" <grahn+n...@snipabacken.se> wrote in message
news:slrnibs1mq.dlt.grahn+nntp@frailea.sa.invalid...
On Tue, 2010-10-19, Jim Langston wrote:
I am developing a font class for my opengl graphics library
and I came across a quandry. I have a font which is simply
a value for font id and wrapper code to load the font and
kill it. Works fine, then I notice I don't have a virtual
destructor, nor any destructor at all. So I throw in
a virtual destructor and call the code to unload the
glfont. I run the program, now no fonts are visible.
The problem is that my fonts are stored in a map by font
name and the font, and of course std::maps along with most
containers use copy.
Put differently: the problem is that you provided a copy
constructor and/or operator=() for something that wasn't
really copyable. Always consider if those should be disabled
for new classes you write.
Actually: How can I use a non-copyable class in a standard container?
You can't, at least not directly. The most general solution
would be a variant on the Letter/Envelope idiom, using deep copy
(which maintains copy semantics). Alternatively, using
boost::shared_ptr works (but with reference semantics).
The problem with a deep copy is that creating the font is extremely
expensive. I'm loading something like 10,000 chars and it takes noticable
time to load the fonts. If I had to do a deep copy use of the font would be
prohibitive.
I've been thinking about a shared pointer, but I remember that C++'s
implementation of the shared pointer was broken in places which is why I
don't use it, and I don't like using boost. I understand that 2010 uses
0x's shared pointers which fix the issues so I may use them, although I
think getting the move to work would be best.
In your specific case, I imagine that the actual font objects
will be immutable once they've been created and fully
initialized. This simplifies things a lot, since for immutable
objects, you can use either value or reference semantics, with
no change in behavior. Depending on how "clean" you want to be,
I'd either settle for shared_ptr, or wrap the shared_ptr in some
sort of handle, along the lines of the letter/envelope idiom (so
that it looks like an object, and not a pointer, to the client
code).
This is how I've handled this situation in the past, although with a wrapped
naked pointer and not a shared pointer. I may wind up using this method.
The problem is that the class can't be copied, at least as it
is, because of the destructor, but containers are loaded by
copy. This problem is common enough that, as I understand it,
in C++0x the std containers will use std::move instead of
copy. Then I could simply disable the copy constructor
(create one and make it private).
I can't comment on the rest, except I don't see why you want
run-time polymorphism for a font handle class.
I don't.
Then why do you want to ban copy? (I would have imagined
polymorphism as the means of supporting different font formats,
e.g. a derived class for TrueType, another for Metafont, etc.)
I want to ban copy because of the prohibitive time taken to initialize a
font.