ScopedPointer private copy constructor


#1

This line:
ScopedPointer box = new MyComponent(…);

trigger this error in gcc 4.4.3:
Libraries/Juce/src/containers/…/containers/juce_ScopedPointer.h:173: error: ‘juce::ScopedPointer::ScopedPointer(const juce::ScopedPointer&) [with ObjectType = juce::MyCompon
ent]’ is private

Even if the compiler shouldn’t have to call the copy constructor here (as “A a = 3;” is supposed to be the same as “A a(3);”), it still checks if it’s accessible.
both microsoft compiler, and previous GCC accept this with no error BTW.

Solution:
Move the copy constructor to a public part, and apply transfert semantics (that is, const_cast the “other” and set it’s internal pointer to 0 without deleting it).


#2

No, it’s correct the way it is.

A const ScopedPointer should be guaranteed to never lose ownership of its object - that’s why the copy constructor deliberately takes a non-const object. Maybe I should put a note in there to explain this.

Besides, any self-respecting c++ guru will tell you to always write “Type a (createType())” rather than “Type a = createType()”. Sure, the compiler will usually figure it out and create good code, but that’s not guaranteed, and the c++ standard has some quite complicated rules about when it can be optimised like that. Much better to get into the habit of writing it the way you expect it to actually be compiled.


#3

I wouldn’t bet my hand on this: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.2
and this: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.19
Beside the fact that this is very difficult to parse (is the former a function declaration called “a” returning “Type”, or an object ?), this is disturbing for a causal-non-C++ programmer (usually any programmer understand a = 3 as an affectation, but not a(3)). Also Juce make use of the later case everywhere (grep for ’ = "’ in the code base)

So suddenly, this works:
Type a(type);
But this doesn’t:
Type a();
// Go figure

Anyway, I agree that philosophically the scope pointer shouldn’t modify it’s pointed object if it’s const, but in reality, code written like “A a = something;” is the current C++ habit (that’s why the standard added a clause “= means call constructor”), and works on Windows, but break on linux when you try to compile your code there. It doesn’t help cross-platformness claimed by the library.


#4

I guess it might look a bit confusing for c++ n00bs, but it’s certainly better to be in the habit of using direct-initialisation instead of copy-initialisation where possible. Herb Sutter’s reason is that the temporary object’s copy constructor could have side-effects that may or may not be performed, depending on whether the compiler chooses to optimise it.

My view is that you always want the compiler to convert “T t = u” into “T t (u)”, and both versions are equally easy to type, so it seems crazy to use the version that’s different from the code you actually want to produce!


#5

Yes you’re right.
It’s a shame they’ve standardized such a confusing construction system.
It’s complex to understand if you don’t have the previous context (that is “T t(u);” can be very different things from function declaration, object construction or macro depending on context)

I now understand better why they are moving the “(u)” in C++x0 to “{u}”.