Am I breaking rule three?

I recently read Rule of Three , and I wonder if I am breaking it?

In my GUI application, classes like MainFrame , Interface , Circuit , Breadboard , etc. (class names are indicative), have one instance of each of them. In my designers, I allocated some resources (memory), which I safely released in my destructors.

So, I defined only the destructor , but not the copy constructor and assignment operator .

I'm sure I don't need them, but I'm curious if I break the rule, and what can I do to follow it?

+3
source share
5 answers

The rule of three is to deal with the whole Big Three, but that does not necessarily mean that you will have to define them if you do not want to. Either you provide them or forbid them. What you should not do is ignore them.


So, I only defined the destructor, but did not copy the constructor and copy operator.
Am I breaking rule three?

Yes, you are breaking the rule. The compiler will generate a copy constructor and copy assignment operator, and since you allocate memory in the constructor and release in the destructor, these copies will have incorrect semantics: they will copy pointers, and you will have two classes superimposing the same name, the Destination will not even release the old memory and just overwrite the pointer.

This is problem?

If, as you mean, you are not making copies or assigning to instances of these classes, nothing will go wrong. Nevertheless, it is better to be safe and declare (and not even interfere with the definition) the copy constructor and copy assignment operator in a private way, so you do not accidentally call them.

In C ++ 11, instead of the = delete syntax, you can use:

 T(T const&) = delete; // no copy constructor T& operator=(T const&) = delete; // no copy assignment 
+6
source

You must declare (but not implement) a private copy constructor and assignment operator. Make sure you are not performing functions. This will prevent any copying of classes that should not be copied.

+2
source

It depends on your application logic and how you documented your user interface classes.

Usually a good C ++ programmer should know a rule of three (and a half if you know the β€œcopy and swap idiom”) and 5 and 1/2 in the case of C ++ 11 (Move semantics).

If the class manages the resource, and if the same class can be copied (that is, copy ctor and the assignment operator, which is not defined as private), then it is very important to do deep copying by writing your own instance of ctor and the assignment operator.

But if you always play in your class, passing them as a HANDBOOK, then it is better to assign the ctor instance and the default assignment operator as private, so even if you pass valy or copy by mistake, the compiler will warn you.

+2
source

Yes, this violates rule three in accordance with this definition.

This, however, is a "rule of thumb". General leadership. If you do not need copy or assign operations, do not perform them. Others suggested declaring them closed and identifying them as empty. I would take another step and say without even defining them.

If you define them, you can potentially call empty methods. Instead, leave them undefined, and if you ever try to call these methods, you will get a linker error because method definitions cannot be found. Thank build time errors for runtime errors / unwanted behavior.

+1
source

If you do not need it, do not follow it. The motivation for rule three is that when you need a destructor, this is usually because you need to make some dynamic releases.

If you also do deallocations, you will need both copy constructors and assignment operators. Imagine you have a class that has a pointer to something:

 struct Foo { Foo() { ptr_ = new int; } ~Foo() { delete ptr_; } int* ptr_; }; 

Since you do not define the copy constructor and assignment operator, whenever you make a copy of Foo , both the original and the copy will use a pointer to the same int ; when either the original or the copy is destroyed, the pointer is freed, and the other - unusable data.

 Foo(cont Foo& other) { other.ptr_ = new int(*ptr_); } // Same for operator= 

If you do not make any dynamic allocations in your constructor / destructor, there is a good chance that you really do not need a copy constructor or an assignment operator (but not necessarily).

+1
source

All Articles