Hello. In the next code, must be written the keyword override in the derived classes or not? It seems to me that the virtual keyword in the base Class is enough in order to allow a redefinition. However, I read that some prefer in the derived classes differents definitions :
#include <iostream>
// base class
class Volume {
protected:
float a;
float b;
float c;
public:
Volume(float a = 1, float b = 1, float c = 1) : a(a), b(b), c(c) {}
virtualfloat computeVolume(void) = 0; // virtual function
void printVolume();
std::string name() const { returntypeid(*this).name(); }
};
void Volume::printVolume()
{
std::cout << this->name() << " : " << this->computeVolume() << std::endl;
}
/////////////////////////////////////////
// box class
class Box : public Volume {
public:
Box(float l, float w, float h) : Volume(l, w, h) {}
float computeVolume() override;
};
// new definition of the virtual function
float Box::computeVolume()
{
std::cout << "Volume for a Box with size " << a << " " << b << " " << c << "\t -> ";
return a * b * c;
}
/////////////////////////////////////////
// sphere class
class Sphere : public Volume {
public:
Sphere(float r) : Volume(r) {}
float computeVolume() override;
};
// new definition of the virtual function
float Sphere::computeVolume()
{
std::cout << "Volume for a Sphere with radius " << a << "\t -> ";
returnfloat(4 * 3.14 * a * a * a) / 3;
}
/////////////////////////////////////////
// square pyramid class
class sPyramid : public Volume {
public:
sPyramid(float l, float h) : Volume(l, h) {}
float computeVolume() override;
};
// new definition of the virtual function
float sPyramid::computeVolume()
{
std::cout << "Volume for a Pyramid with size " << a << " " << b << "\t -> ";
return ((float)1/3 * a * a * b);
}
/////////////////////////////////////////
int main()
{
Volume* v1 = new Box(4, 5, 6);
Volume* v2 = new Sphere(3.7f);
Volume* v3 = new sPyramid(4.2f, 5.5f);
v1->printVolume();
v2->printVolume();
v3->printVolume();
delete v1;
delete v2;
delete v3;
return 0;
}
Volume for a Box with size 4 5 6 -> class Box : 120
Volume for a Sphere with radius 3.7 -> class Sphere : 212.067
Volume for a Pyramid with size 4.2 5.5 -> class sPyramid : 32.34
An override on a derived class function ensures that you are actually overriding a base class function - and not defining a new one eg by accident. You don't specify override on a base class function.
virtual - if needed - is applied to the base function. It can (but doesn't need to be) applied to derived class functions. A base virtual final function spec makes no sense at all!
> Is it your favorite reference when there is a question or a doubt?
It is a useful set of guidelines, easily available to everyone.
Perhaps unnecessarily strict and too dogmatic; hopefully over a period of time, it would also cover programming situations which warrant a relaxation of some of these rules.
When a base class is intended for polymorphic use, its destructor may have to be declared public and virtual. This blocks implicit moves (and deprecates implicit copies), and so the special member functions have to be declared as defaulted
...
however, this makes the class prone to slicing, which is why polymorphic classes often define copy as deleted which leads to the following generic wording for the Rule of Five:
C.21: If you define or =delete any default operation, define or =delete them all https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_zero