Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In new c++11 projects, should I delete any operations by default?

I am starting a new project in C++11, and just found out about the delete keyword that lets you prevent accidental calling of copy constructors and so on. Is there a "recommended" set of deletions I can do globally to increase type safety, such as preventing signed to unsigned cast within expressions? Should I default to deleteing all 5 operations that I can delete in all my classes?

FYI, this program requires high performance (thats why I'm using C++, for the first time in years) and there are very few times I want to copy anything, so a copy is usually a bug, although not 100% of the time, so I'm interested in this specific case, as well as the general case for other programs. I could potentially delete the copy constructor and add a separate method that copies the object for the rare time that I do need a copy. Would that be a good idea?

like image 303
Drew Avatar asked Dec 11 '22 00:12

Drew


1 Answers

Is there a "recommended" set of deletions I can do globally to increase type safety, such as preventing signed to unsigned cast within expressions?

No. You certainly can't prevent integer conversions by deleting anything.

Should I default to deleteing all 5 operations that I can delete in all my classes?

No! A deleted destructor would make it impossible to destroy anything!

Also, deleting a move constructor rarely makes sense. If your type can be moved cheaply then allowing moves (e.g. when returning objects by value, or passing temporaries by value as function arguments) is usually a good thing, even if you don't want to allow copies. Artificially restricting users of the type from moving it when doing so is efficient is just annoying and doesn't provide any advantages.

You seem to be falling into the trap of seeing a feature is available and thinking you should use it. The following quote from The Old Man and the C seems relevant:

One final anecdote regarding the earlier story where someone used an int reference parameter. In discussing this paper, the programmer's comment was - "Well, the feature was in the language so I figured I should use it.". It is our belief that this is not a sufficient criteria for using a feature of C++. A feature should be used only when it can be demonstrated to be of benefit. A mountain is climbed "because it is there". The same should not hold true for C++ features. Their mere existence is not justification for use.

As for your final question:

I could potentially delete the copy constructor and add a separate method that copies the object for the rare time that I do need a copy. Would that be a good idea?

... maybe ... this might be a case where a deleted copy constructor can be demonstrated to be of benefit. But I would say generally no, don't do that, because it makes it difficult to store the object in containers, for example. It is better to just write your code carefully to avoid unwanted copies. If you're failing to do that and have demonstrated you really are making accidental copies, maybe reconsider deleting the copy constructor.

But you should not be deleting operations "by default" just because you've learnt about the feature. It should be much more common to use = default rather than = delete except for classes that model some atypical behaviour, such as unique-ownership of a resource.

like image 161
Jonathan Wakely Avatar answered Mar 08 '23 10:03

Jonathan Wakely