Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rule of three and inheritance

class A defines copy operator, destructor and operator=. (Rule of Three)

If B inherits from A:

  • the destructor will be called automatically
  • I need to chain the constructor
  • operator= ... should I define it explicitly for the class B?
like image 394
Jakub M. Avatar asked Oct 25 '11 07:10

Jakub M.


People also ask

What is the rule of three five regarding designing a class?

The rule of three and rule of five are rules of thumb in C++ for the building of exception-safe code and for formalizing rules on resource management. The rules prescribe how the default members of a class should be used to achieve these goals systematically.

What is the rule of 3 stack overflow?

In that case, remember the rule of three: 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. (Unfortunately, this "rule" is not enforced by the C++ standard or any compiler I am aware of.)

What is the rule of 5 CPP?

The Rule of Five is a modern extension to the Rule of Three. The Rule of Five states that if a type ever needs one of the following, then it must have all five. In addition to copy semantics (Rule of Three), we also have to implement move semantics.

What is the rule of zero?

“The Rule of Zero” basically states: You should NEVER implement a destructor, copy constructor, move constructor or assignment operators in your code. With the (very important) corollary to this: You should NEVER use a raw pointer to manage a resource.


2 Answers

No, it's unnecessary.

If you read carefully the Rule of Three, you will notice that nothing is said about a base class, the decision is made solely on the class proper attributes and behavior.

(Check this example on ideone)

#include <iostream>

struct A {
  A(): a(0) {}
  A& operator=(A const& rhs) { a = rhs.a; return *this; }
  int a;
};

struct B: A { B(): b(0) {} int b; };

int main() {
  B foo;
  foo.a = 1;
  foo.b = 2;

  B bar;
  bar = foo;

  std::cout << bar.a << " " << bar.b << "\n";
}

// Output: 1 2

This is actually the true power of encapsulation. Because you succeeded, using the Rule of Three, in making the behavior of the base class sane, its derived classes need not know whether the copy constructor is defaulted by the compiler or implemented manually (and complicated), all that matters for a user (and a derived class is a user), is that the copy constructor performs the copy.

The Rule of Three reminds us of an implementation detail to help achieve correct semantics. Like all implementation details, it matters only to the implementer and maintainer of this class.

like image 65
Matthieu M. Avatar answered Sep 21 '22 07:09

Matthieu M.


Same Rule of Three applies to the derived class as well.
The Rule is applicable to all classes and you can apply it to each class down an Inheritance hierarchy same as you apply it to a single class.

If your class B needs any of the two(Copy Constructor & Destructor) of the Big Three then you need to define the copy assignment operator as well.

So it actually depends on the members of the Derived class & the behavior you want for your Derived class objects.

For example:
If the derived class members consists of any pointer members and you need deep copies then as per the Rule of Three your derived class needs to overload and provide own implementations for the Big Three.

like image 25
Alok Save Avatar answered Sep 23 '22 07:09

Alok Save