3

I've read that The Rule of Three, What is The Rule of Three? is summarized as follows:

If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.

My question is: In a C++ application, I have a class that manages resources (has a destructor that handles deleting pointers). I know that the application uses assignment operator all over the place, but I am absolutely certain that there is no usage in the application of a copy constructor, i.e., usage of the type Class c(..); Class d(c); so under these circumstances, am I still required to implement both an assignment operator and a copy constructor? Or will an assignment operator alone suffice? Is it possible that the assignment operator uses the copy constructor somehow?

Appreciate your thoughts.

Community
  • 1
  • 1
squashed.bugaboo
  • 1,338
  • 2
  • 20
  • 36
  • Even if you don't use something now, you might decide to later, and end up in a hole. – chris Jun 13 '12 at 22:49
  • 2
    C++ it will create a default constructor/copy constructor/default destructor if not specified for you, which most of the time wil do some pretty bad things, depending on your structure, if ever called explicitly/implicitly. – Samy Vilar Jun 13 '12 at 22:51
  • Even if you're absolutely certain it's not being used now it may be used later (say if you return the object from a function) ... the gist of the rule is when the default implementation for one isn't good enough the default implementation for others usually won't be either so it's better to cover all the bases. – AJG85 Jun 13 '12 at 23:16
  • Possible duplicate of [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – roottraveller Oct 17 '16 at 04:22

3 Answers3

13

If you know that the copy constructor won't be used, you can express that by making it private and unimplemented, thus:

class C
{
private:
    C(const C&); // not implemented
};

(in C++11 you can use the new = delete syntax). That said, you should only do that if you're absolutely sure it will never be needed. Otherwise, you might be better off implementing it. It's important not to just leave it as is, as in that case the compiler will provide a default memberwise copy constructor that will do the wrong thing - it's a problem waiting to happen.

To some extent it depends on what the class is going to be used for - if you're writing a class that's part of a library, for instance, it makes much more sense to implement the copy constructor for consistency reasons. You have no idea a priori how your class is going to be used.

Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
  • Thanks @Golodetz. I like this idea. Will try it out. – squashed.bugaboo Jun 13 '12 at 22:54
  • Would this work in a struct also? I have some structs also that manage resources.. – squashed.bugaboo Jun 13 '12 at 22:57
  • 2
    Yes, it works for structs as well. A struct is just like a class except for the default public access and public inheritance. That said, if you're managing resources then it's arguably more idiomatic to use the `class` keyword - managing resources in a struct feels odd somehow. Structs are a hangover from C, and even though there's little difference between structs and classes in C++, it's still more usual to continue to use them primarily in a C-like way. – Stuart Golodetz Jun 13 '12 at 22:57
  • Thanks, this is not in my code though.. and it is huge. But it good to know this works for structs as well. Thanks. – squashed.bugaboo Jun 13 '12 at 23:11
  • @squashed.bugaboo The only real difference between structs and classes is that structs are default public scope and classes are default private scope. – AJG85 Jun 13 '12 at 23:17
  • @StuartGolodetz, To confirm, you **can** use `= delete`, works great. Plus then you can't accidentally internally use it. – chris Jun 13 '12 at 23:30
  • Thanks chris :) I said it a little tentatively because I haven't used many of the new features "in anger" yet - the compilers were still catching up at the point I switched over to doing some Java coding again. – Stuart Golodetz Jun 14 '12 at 00:03
4

I am absolutely certain that there is no usage in the application of a copy constructor, i.e., usage of the type Class c(..); Class d(c)

Are you aware that the following code

Foo c;
Foo b = c;

invokes the copy constructor and NOT the assignment operator? I'd implement the copy constructor just to be safe.

Doug T.
  • 64,223
  • 27
  • 138
  • 202
  • Thanks @Doug: Yes, I am aware of this fact, but I only have usages such as Foo& b = c. – squashed.bugaboo Jun 13 '12 at 22:52
  • 3
    Better yet, make the class non-copyable and let the compiler/linker tell you if you violated your own invariant. Zero overhead, zero effort. – ildjarn Jun 13 '12 at 22:53
1

In almost all cases, the compiler will generate these methods for you and you don't need to do anything. But, if implicitly generated copy constructor/assignment operator won't do what you want, and design-wise your class makes sense to be able to be copied, you should explicitly provide a copy ctor and assignment operator whether you use them both or not (as good practice).

If, design-wise, your class makes sense to be noncopyable, you can declare but not define the copy ctor/assignment op.

David
  • 27,652
  • 18
  • 89
  • 138
  • If you have any pointer stored in fields, then the default will be wrong 99% of the time. – Ian Ringrose Jan 09 '14 at 20:02
  • @IanRingrose Only true for outdated C++ practices. These days, raw pointers should _never_ represent ownership. – David Jan 09 '14 at 20:54
  • The problem is that most C++ code in the world is outdated, just think of how much MFC is still about!!! – Ian Ringrose Jan 09 '14 at 23:06
  • @Ian Interacting with outdated code isn't an excuse to promote continued use of outdated practices. Nice try though. – David Jan 10 '14 at 03:21
  • what reason is there to use C++ rathern then Java or C# for **most** software unless you have outdated code in the system? – Ian Ringrose Jan 10 '14 at 11:44
  • @IanRingrose Should I even reply to such a stupid comment? I guess... Games, server software, partly ios/mac, cross platform mobile, embedded, and many more. You obviously live in the world of GUI desktop tools. I know it's hard to believe, but there is more in the world than that. – David Jan 10 '14 at 15:04