On 22/10/2010 06:11, Jim Langston wrote:
"Bo Persson" <bop@gmb.dk> wrote in message
news:8ibae2F8drU1@mid.individual.net...
Jim Langston wrote:
"Jim Langston" <tazmaster@rocketmail.com> wrote in message
news:i9j7i2$73r$1@four.albasani.net...
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.
Resolution:
I used Microsoft Express 2010 C++0x utilization of std::move for
containers.
I had a problem implementing this because when I first created a
move constructor I was still using assignment in my code. I
disbled the assignment operator and fixed my code and it works as
advertised. I had to change the elegant line of:
world.fonts[L"Normal"] = jmlGL::jglFont( hDC, L"Courier New",
24 ); to the no where near as elegant line of:
world.fonts.insert(std::pair<std::wstring, jmlGL::jglFont>(
L"Normal", jmlGL::jglFont( hDC, L"Courier New", 24 ) ) );
my program worked as expected and I am able to use non-copyable
objects in a container.
Wouldn't another soultion be to implement a move assignment operator
for foo?
foo& operator=(foo&&);
That would let you assign a temporary (rvalue only) to the mapped
object.
I was thinking about this, but if every time I did an assignment I moved
ownership I wouldn't like that. Java does that and it bugs the heck out
of me. As I understand it if I have operator=(&&) then the compiler
will use this instead of operator= (although I might be mistaken in
that). I just don't like the idea of accidently changing ownership
without realzing it since that is not the "normal" behavior of
operator=. I'll have to research that more before I implement it, and I
had thought about implementing it also but am not aware of all the
effects. Disabling operator= and creating the move constructor allow me
to use the object as intended. Only one real copy of the object
exists, almost like a singleton pattern.
Bo Persson
You are indeed mistaken. One of the reason rvalue refs are in the upcoming
C++0x standard is because they make moving semantics safe. Consider
auto_ptr, where ownership *can* accidentally be lost. On the other hand,
this can't happen with unique_ptr (its replacement). To move a unique_ptr
through assignment from an lvalue, you have to request it, as in:
std::unique_ptr<T> original = /* initialize here */
std::unique_ptr<T> dest = original; // won't compile
std::unique_ptr<T> safe_dest = std::move(original);
// don't use original anymore
So if you class has an operator=(&&), but not a copy assignment operator
(operator=(const&), but also operator=(&)), you can't accidentally
invalidate your objects. Although check that your implementation actually
*does* that since the specs for rvalue refs have been in flux for some
time.
justified. Without an operator=(&&) this will not compile (as it shouldn't).
my program compiles and runs. I did not have to use std::move.