Re: canceling noncopyable feature
mzdude wrote:
On Aug 27, 2:25 pm, Noah Roberts <roberts.n...@gmail.com> wrote:
mzdude wrote:
On Aug 27, 11:55 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
Fraser Ross wrote:
Thats a big problem. noncopyable doesn't do its job as well as I
thought.
It doesn't necessarily means that it's not doing its job *as intended*,
and what you thought isn't necessarily what was intended. What do you
think it would do? Make any descendant class non-copyable?
Yes. Perhaps changing the boost::noncopyable object to hide it's
default
ctor would help.
Then if you have a class derrived from it
class MyClass : boost::noncopyable
{
MyClass() : boost::noncopyable( some_trait ) {}
// then
MyClass( const MyClass &tocpy ) {}
would error because the compiler would subsitute the default
ctor for noncopyable which would be hidden.
I don't think that noncopyable is meant to keep you from blowing your
brains out. It's meant to be a somewhat language enforced method of
documenting a known aspect of an interface. Anything that derives from
noncopyable is not meant to be copied, that's what the relationship is
documenting. The rest just keeps the compiler from self-generating the
copyable interface...I don't think it was ever meant to try rescuing
people from their own stupidity and I don't see how it even could.
I know macros have a reputation for being *evil* but I think
the following documents the interface and doesn't bring along
any of the derived interface baggage.
I don't think there's much baggage being brought along. The noncopyable
class is meant to be inherited from privately.
#define NON_COPYABLE(x) private: \
##x(##x const & ); \
##x &operator=(##x const ref) const;
class MyClass
{
public:
MyClass();
NON_COPYABLE(MyClass)
};
Except the error generated using the noncopyable class will have
"noncopyable" in it:
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(6) : error
C2248: 'boost::noncopyable_::noncopyable::noncopyable' : cannot access
private member declared in class 'boost::noncopyable_::noncopyable'
1> d:\boostvs39\include\boost\noncopyable.hpp(27) : see
declaration of 'boost::noncopyable_::noncopyable::noncopyable'
1> d:\boostvs39\include\boost\noncopyable.hpp(22) : see
declaration of 'boost::noncopyable_::noncopyable'
1> This diagnostic occurred in the compiler generated function
'myclass::myclass(const myclass &)'
your version:
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(15) : error
C2512: 'myclass' : no appropriate default constructor available
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(16) : error
C2248: 'myclass::myclass' : cannot access private member declared in
class 'myclass'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(10) :
see declaration of 'myclass::myclass'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(9) :
see declaration of 'myclass'
Also note the extra error regarding the default constructor with yours.
You can't let the default constructor be compiler generated in your
version.
The code:
#define NON_COPYABLE(x) private: \
##x(##x const&); \
##x &operator=(##x const ref) const;
struct myclass
{
NON_COPYABLE(myclass)
};
int main()
{
myclass a;
myclass b = a;
}
And with noncopyable myclass was defined as:
struct myclass : private boost::noncopyable
{
};
So the benefits of using boost::noncopyable over your macro would seem
to me to be:
1) the statement "noncopyable" in the diagnostic error.
2) the ability to use default constructors.
You say there's derived interface baggage but since you inherit
privately I don't think that even affects derived classes that might
also inherit from noncopyable. I don't see any pollution of the
interface since private inheritance is not an is-a type of relationship.