
On 12/19/04 7:43 AM, "Dirk Gregorius" <dirk@dirkgregorius.de> wrote:
Does it really make any sense making only implementation noncopyable, rather than interface? If you deal with interfaces only it won't save you from errors like this:
std::auto_ptr<Interface> create() { return std::auto_ptr<Interface>(new Implementation); }
void foo() { std::auto_ptr<Interface> a(create()), b(create());
*a = *b; // oops, no error here, Implementation::operator= // is not considered }
I saw some code that declared the copy operations private in the base class.
class Interface { public: virtual void f() = 0;
private: Interface( const Interface& ); Interface& operator=( const Interface& ); }
So in order to gain maximum style and correctness points I need to make both classes ( Interface and Implementation ) noncopyable? Which means both need to derive from boost::noncopyable?
I think that this is a bad idea. If "Interface" has no data members, then it's better to leave the copying operations unspecified. Manually inserting copy-blocking declarations does more harm than good. It does not provide a ban on derived classes ever getting copy operations, since the derived class's copy constructor can use _any_ base class constructor and the derived class's assignment operator doesn't have to call the base class's assignment operator. (A derived class can't have automatically defined copy operations, though; the evil copying operations have to be explicitly written.) Worse, the "Interface" class as given has no usable constructors, because the private & undefined copy constructor STILL cancels the automatically defined default constructor! Granted, the presence of a pure virtual member function already bans creation of "Interface" objects, but no derived classes can be made either. As I implied, let the automatically defined copy operations for abstract classes work. This applies to abstract classes with no data members that have problems automatically managing their resources (includes classes with no data members at all). For members that need explicit copying management, like shared pointer class internals, then provide protected versions of the standard copying operations. Ban the copying operations only if there is no way to create sane copying semantics.
BTW:
Why is this possible? Does it make sense to dereference an interface?
No, it doesn't make sense for what you wrote next. It's possible because C++ in general (along with C) does not censor what you do with return values.
Interface* p1 = make_interface(); Interface* p2 = make_interface();
*p1 = *p2;
Unless the "Interface" assignment operator is virtual, this will do slicing! That will be very bad in general. Note that automatically defined operations are never virtual. In the case here, making a protected assignment operator may help by making the compiler spit out an access error (unless this code is within a derived class's method).
Or does your example only work with auto/smart pointers?
-- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com