2

Currently I read the book Effective Modern C++ from Scott Meyers, and now I'm at: Item 17: Understand special member function generation.

My misunderstanding comes from the following part (rationale):

The two copy operations are independent: declaring one doesn’t prevent compilers from generating the other. So if you declare a copy constructor, but no copy assignment operator, then write code that requires copy assignment, compilers will generate the copy assignment operator for you. Similarly, if you declare a copy assignment operator, but no copy constructor, yet your code requires copy construction, compilers will generate the copy constructor for you. That was true in C++98, and it’s still true in C++11.

The two move operations are not independent. If you declare either, that prevents compilers from generating the other. The rationale is that if you declare, say, a move constructor for your class, you’re indicating that there’s something about how move construction should be implemented that’s different from the default memberwise move that compilers would generate. And if there’s something wrong with memberwise move construction, there’d probably be something wrong with memberwise move assignment, too. So declaring a move constructor prevents a move assignment operator from being generated, and declaring a move assignment operator prevents compilers from generating a move constructor.

I think the rationale part could be applied to the copy constructor and copy assignment operator pair also, couldn't it ? So if I declare a copy constructor I indicate with it that the default memberwise copy is not adequate for me. And if I say this than probably the copy assignment operator should be user defined also.

I think it's a great book, but at this point this rationale is not clear for me. Please help and explain this for me. Thanks.

p.i.g.
  • 2,815
  • 2
  • 24
  • 41
  • 1
    Backward compatibility is the reason. Worth noting that implicitly generating a copy operation when a copy operation (or the destructor) is user-declared is deprecated. – T.C. Aug 05 '15 at 17:18
  • 1
    Yes, that's how it should've been. A user declared copy constructor should prevent implicit declaration of a copy assignment operator and vice versa. Similarly, a user declared destructor should prevent implicit declaration of both copy special members, and C++11 deprecates these cases. But doing away with them completely would break a lot of existing code. – Praetorian Aug 05 '15 at 17:22
  • Answered here: http://stackoverflow.com/a/11255258/576911 – Howard Hinnant Aug 07 '15 at 14:10

1 Answers1

3

I think the rationale part could be applied to the copy constructor and copy assignment operator pair also, couldn't it ?

Absolutely. The standard agrees with you. In [class.copy]:

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

And:

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.

Of course there's probably a lot of existing code that would break if the "latter cases" in question were done away with immediately, which is why the Standard moved first to deprecation and will only remove them at some arbitrarily distant point in the future.

Then again, even long-deprecated-and-since-removed features have a way of hanging around long past their welcome. Like char * s = "MyString";

Community
  • 1
  • 1
Barry
  • 286,269
  • 29
  • 621
  • 977