Aug 27, 2022 at 11:30am Aug 27, 2022 at 11:30am UTC
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 :
virtual myFunction(arg) override { ... }
myFunction(arg) override { ... }
myFunction(arg) { ... }
All these alternatives work as expected, but I guess that some are better than others. Thanks for your help. Have a nice day ++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#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) {}
virtual float computeVolume(void ) = 0; // virtual function
void printVolume();
std::string name() const { return typeid (*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 -> " ;
return float (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
Last edited on Aug 27, 2022 at 11:33am Aug 27, 2022 at 11:33am UTC
Aug 27, 2022 at 12:27pm Aug 27, 2022 at 12:27pm UTC
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!
Last edited on Aug 27, 2022 at 3:47pm Aug 27, 2022 at 3:47pm UTC
Aug 27, 2022 at 3:15pm Aug 27, 2022 at 3:15pm UTC
Thank you for your advices and links.
The Core Guidelines seems interesting.
Is it your favorite reference when there is a question or a doubt?
Last edited on Aug 27, 2022 at 3:15pm Aug 27, 2022 at 3:15pm UTC
Aug 27, 2022 at 3:44pm Aug 27, 2022 at 3:44pm UTC
It is fine, even if it conveys superfluous, (non-contradictory) information:
I meant:
1 2 3
struct A {
virtual void foo() final {};
};
[Changed my reply above]
Last edited on Aug 27, 2022 at 3:45pm Aug 27, 2022 at 3:45pm UTC
Aug 27, 2022 at 3:56pm Aug 27, 2022 at 3:56pm UTC
> 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.
Last edited on Aug 27, 2022 at 3:58pm Aug 27, 2022 at 3:58pm UTC
Aug 27, 2022 at 4:00pm Aug 27, 2022 at 4:00pm UTC
virtual float computeVolume(void ) = 0; // virtual function
You don't need void here in C++. You do:
virtual float computeVolume() = 0; // virtual function
printVolume() and computeVolume() should be const as they don't change the member variables.
Without a virtual Volume destructor, compiler (at least VS) spews out warnings.
Why use float and not double?
Since C++20 common constants (like pi) are defined.
https://en.cppreference.com/w/cpp/numeric/constants
Note that pi etc (without the _v) are defined for double. So for float we need the _v version with a specified type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include <iostream>
#include <numbers>
// 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) {}
virtual float computeVolume() const = 0; // virtual function
void printVolume() const ;
std::string name() const {
return typeid (*this ).name();
}
virtual ~Volume() {} // To avoid compiler warnings!
};
void Volume::printVolume() const {
std::cout << name() << " : " << computeVolume() << '\n' ;
}
/////////////////////////////////////////
// box class
class Box : public Volume {
public :
Box(float l, float w, float h) : Volume(l, w, h) {}
float computeVolume() const override;
};
// new definition of the virtual function
float Box::computeVolume() const {
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() const override;
};
// new definition of the virtual function
float Sphere::computeVolume() const {
std::cout << "Volume for a Sphere with radius " << a << "\t -> " ;
return float (4.0f * std::numbers::pi_v<float > * a * a * a) / 3.0f;
}
/////////////////////////////////////////
// square pyramid class
class sPyramid : public Volume {
public :
sPyramid(float l, float h) : Volume(l, h) {}
float computeVolume() const override;
};
// new definition of the virtual function
float sPyramid::computeVolume() const {
std::cout << "Volume for a Pyramid with size " << a << " " << b << "\t -> " ;
return (a * a * b) / 3.0f;
}
/////////////////////////////////////////
int main() {
const Volume* v1 { new Box(4, 5, 6) };
const Volume* v2 { new Sphere(3.7f) };
const Volume* v3 { new sPyramid(4.2f, 5.5f) };
v1->printVolume();
v2->printVolume();
v3->printVolume();
delete v1;
delete v2;
delete v3;
}
Last edited on Aug 27, 2022 at 4:18pm Aug 27, 2022 at 4:18pm UTC