c++ Pure virtual functions dependent on derived classes - c++

I am working on a bounding box/collision detection system and I am using different types of bounding volumes, id like all the bounding volumes to derive the same base class and then using pure virtual functions forcing all derived classes to implement basic functions like
isCollidingWith(BoudingBox)
But here is what giving me trouble: I wan't them to implement a function for every BoudingVolume type. So if I have a bounding box and a bounding sphere, both the sphere class and the box class should implement
isCollidingWith(BoundingBox)
isCollidingWith(BoundingSphere)
If i then create a new BoundingVolume like BoundingCylinder (by deriving from the base class), i want the compiler to throw an error until BoundingBox and BoundingSphere has implemented the isCollidingWith function for the new Cylinder type (and ofc until the Cylinder has implemented the isCollidingWith for the Box, Sphere and the Cylinder.
Im not sure on how to go about implementing this, but I thought about using CRTPs.
Is this even possible?

When you make pure virtual function in base class, then it is compulsory for derived class for its implementation, if derived class doesn't implement it then compiler will give you an error. so you don't have to take care whether the pure virtual functions are implemented or not.

It is possible to concoct such a thing with CRTP
class BoundingBox;
class BoundingSphere;
class Shape
{
public:
virtual bool isIntersecting(const BoundingBox&) const = 0;
virtual bool isIntersecting(const BoundingSphere&) const = 0;
};
class BoundingVolumeBase
{
public:
virtual bool checkIntersection(const Shape&) const = 0;
virtual ~BoundingVolumeBase();
};
template<class Derived>
class BoundingVolume : public BoundingVolumeBase
{
bool checkIntersection(const Shape& shape) const override
{
return shape.isIntersecting (static_cast<const Derived&>(*this));
}
};
class BoundingBox : public BoundingVolume<BoundingBox> {
// ...
};
class BoundingSphere : public BoundingVolume<BoundingSphere> {
// ...
};
Now if we invent a new kind of BoundingVolume, it will not compile until a new function is added to Shape.
class BoundingCylinder : public BoundingVolume<BoundingCylinder> {
// ...
};
BoundingCylinder bc; // <-- this will not compile
It is not necessary to do it this way. Any method that uses virtual functions as the sole kind of type-based dispatch will work (you will likely end up with something roughly equivalent to the above anyway). If you depend on typeid or on a custom type identifier, you may encounter problems though.
The downside of this method is mutual dependence of class Shape and all concrete kinds of BoundingVolume.

Related

Can I have a non-virtual abstract class in C++ [duplicate]

I have a base class
class ShapeF
{
public:
ShapeF();
virtual ~ShapeF();
inline void SetPosition(const Vector2& inPosition) { mPosition.Set(inPosition); }
protected:
Vector2 mPosition;
}
Obviously with some ommitied code, but you get the point.
I use this as a template, and with some fun (ommited) enums, a way to determine what kind of shape i'm using
class RotatedRectangleF : public ShapeF
{
public:
RotatedRectangleF();
virtual ~RotatedRectangleF();
protected:
float mWidth;
float mHeight;
float mRotation;
}
ShapeF does its job with the positioning, and an enum that defines what the type is.
It has accessors and mutators, but no methods.
Can I make ShapeF an abstract class, to ensure nobody tries and instantiate an object of type ShapeF?
Normally, this is doable by having a pure virtual function within ShapeF
//ShapeF.h
virtual void Collides(const ShapeF& inShape) = 0;
However, I am currently dealing with collisions in a seperate class.
I can move everything over, but i'm wondering if there is a way to make a class abstract.. without the pure virtual functions.
You could declare, and implement, a pure virtual destructor:
class ShapeF
{
public:
virtual ~ShapeF() = 0;
...
};
ShapeF::~ShapeF() {}
It's a tiny step from what you already have, and will prevent ShapeF from being instantiated directly. The derived classes won't need to change.
Try using a protected constructor
If your compiler is Visual C++ then there is also an "abstract" keyword:
class MyClass abstract
{
// whatever...
};
Though AFAIK it will not compile on other compilers, it's one of Microsoft custom keywords.

CRTP with pure abstract base class : call overhead

I am using CRTP for some classes. However, I need to homogeneously store these classes for example in an std::vector.
A solution would be to have a common abstract base class. For example, as explained in the wikipedia page on CRTP :
// Base class has a pure virtual function for cloning
class Shape {
public:
virtual ~Shape() {};
virtual void draw() = 0;
};
// This CRTP class implements clone() for Derived
template <typename Derived>
class Shape_CRTP : public Shape {
public:
void draw() {
static_cast<Derived const&>(*this)->draw();
}
};
class Square: public Shape_CRTP<Square> {
void draw() {/// implement draw}
};
class Circle: public Shape_CRTP<Circle> {
void draw() {/// implement draw}
};
and in the main :
std::vector<Shape*> shapes;
for (auto s : shapes) {
s->draw();
}
But in this case, don't I lose the benefits of static polymorphism as I will have the virtual call overhead (draw is virtual in the common base class), and as my draw implementations will not be inlined?
Please explain and point me to references if you have some
First and most important, let's state the reason for CRTP: it is a tool for code reduction. The corresponding base class is hardly ever used by itself, but rather to implement functions which are shared by several derived classes (and which you'd otherwise would have to retype in any derived class anew).
In CRTP, it is good style to separate the "pure virtual functions", which are to be implemented in the derived class, via their name. I usually use the suffix _impl for that and put the functions in protected scope. This directly tells you which of the functions in the CRTP base class one should implement in derived classes (whereas the others would work out of the box).
Applied to your example this would look like the following:
struct Shape {
virtual ~Shape() {};
virtual void draw() const = 0;
};
template <typename Derived>
struct Shape_CRTP : public Shape {
protected:
void draw_impl() const = delete;
public:
virtual void draw() const override final {
static_cast<Derived const&>(*this).draw_impl();
}
};
struct Square: public Shape_CRTP<Square> {
friend Shape_CRTP<Square>;
protected:
void draw_impl() const {/* implement draw */}
};
struct Circle: public Shape_CRTP<Circle> {
friend Shape_CRTP<Circle>;
protected:
void draw_impl() const {/* implement draw */}
};
Let's look at this from the perspective of performance:
When you work with a pointer to the virtual base class Shape, the previous solution is equivalent to yours. In both cases you have a dynamic access via a vtable, and this has the same overhead regardless of the dept of the inheritance hierarchy (i.e. regardless whether you point to Square as in your solution or to Shape_CRTP<Square> as in mine).
When you work directly with the derived class Square, it's also equivalent, because then the compiler can call the draw() function directly (either via the derived class in your solution or via the CRTP base in mine).
And, as said, one hardly ever works with Shape_CRTP directly, so there is also no point in analysing its behavior.
Summarizing, CRTP has no effect on the runtime performance here. So, why you should need CRTP at all? Again, for code reduction! An this pays out the most, if you have
either only a few _impl() functions to derive from, and a whole lot of functions in the CRTP base class, or
a lot of different derived classes, where saving a few function implementations could be worth it.
Depending on the actual problem, CRTP can save thousands lines of code, and in general, it's a great tool exactly for that.

C++ abstract class without pure virtual functions?

I have a base class
class ShapeF
{
public:
ShapeF();
virtual ~ShapeF();
inline void SetPosition(const Vector2& inPosition) { mPosition.Set(inPosition); }
protected:
Vector2 mPosition;
}
Obviously with some ommitied code, but you get the point.
I use this as a template, and with some fun (ommited) enums, a way to determine what kind of shape i'm using
class RotatedRectangleF : public ShapeF
{
public:
RotatedRectangleF();
virtual ~RotatedRectangleF();
protected:
float mWidth;
float mHeight;
float mRotation;
}
ShapeF does its job with the positioning, and an enum that defines what the type is.
It has accessors and mutators, but no methods.
Can I make ShapeF an abstract class, to ensure nobody tries and instantiate an object of type ShapeF?
Normally, this is doable by having a pure virtual function within ShapeF
//ShapeF.h
virtual void Collides(const ShapeF& inShape) = 0;
However, I am currently dealing with collisions in a seperate class.
I can move everything over, but i'm wondering if there is a way to make a class abstract.. without the pure virtual functions.
You could declare, and implement, a pure virtual destructor:
class ShapeF
{
public:
virtual ~ShapeF() = 0;
...
};
ShapeF::~ShapeF() {}
It's a tiny step from what you already have, and will prevent ShapeF from being instantiated directly. The derived classes won't need to change.
Try using a protected constructor
If your compiler is Visual C++ then there is also an "abstract" keyword:
class MyClass abstract
{
// whatever...
};
Though AFAIK it will not compile on other compilers, it's one of Microsoft custom keywords.

Base and child class function inheritance confusion (C++)

I am very confused about base and child class function inheritance.
I have those classes:
#include <point.h>
class Polygon{
public:
Polygon();
virtual ~Polygon();
void addPoint(Point *p);
std::string getType();
Point* getPoint(int index);
int getNumOfPoints();
int getColor();
virtual int area()=0;
private:
std::vector<Point*> _points;
int color;
std::string type = "Polygon";
};
class Rectangle : public Polygon{
public:
Rectangle();
virtual ~Rectangle();
virtual int area();
private:
std::vector<Point*> _points;
int color;
std::string type = "Rectangle";
};
Now, in the main I do this:
Rectangle rect();
rect.getType();
this gives me "Polygon" while I want "Rectangle"
I am quite sure I am confused with inheritance. So, according to how I understand, the base class functions get inherited, but why is it when I run the function it relates to the members of the object base class but not the actual object (Rectangle)?
Will be happy if someone would help!
Much appreciated
What happens is that Rectangle::type is completely unrelated to Polygon::type. It's a separate data member that just happens to have the same name.
One way to achieve the desired effect is by making getType() virtual and overriding it in every derived class:
class Polygon {
public:
virtual std::string getType() = 0;
...
}
class Rectangle: public Polygon {
public:
virtual std::string getType();
...
}
std::string Rectangle::getType() {
return "Rectangle";
}
You have two members named type in an instance of Rectangle. Since private members of Polygon are only accessible to the member functions of that class, it's as if they didn't exist when it comes to declaring members by the same name in Rectangle. It's not even shadowing proper, because in Rectangle, the type member of Polygon would not be accessible. So Polygon::getType returns the type defined in Polygon and not the unrelated one defined in Rectangle.
You have several ways to solve your issue:
Define type as a protected member in Polygon and assign to it in every constructor.
Drop type; declare getType as virtual and override it in every class, returning a constant string.
Use RTTI for what it's good for: finding out the actual class of an object.
Design your program so that you don't need to tell the exact type of an object. This is usually best. Every time you need different behavior for different subclasses of Polygon, write a virtual member function that implements the specific behavior.
You only need the type string in one place - your base class. Because you want it to be accessible in your derived classes but not to your user, make it protected. In each constructor, set it to the appropriate value:
Polygon::Polygon():
type("polygon")
{}
Rectangle::Rectangle()
Polygon()
{
type = "rectangle";
}

Is it possible to return a derived class from a base class method in C++?

I would like to do this:
class Derived;
class Base {
virtual Derived f() = 0;
};
class Derived : public Base {
};
Of course this doesn't work since I can't return an incomplete type. But neither can I define Derived before base, since I can't inherit from an incomplete type either. I figure that I could use templates as a workaround (using Derived as a template argument to Base), but it seems a really ugly way of doing things. Might there be another way?
Elaboration: I'm writing a raytracer, and each Shape class has a function which returns its bounding box. However, I've made the BBox a subclass of Shape, so I can visualize it. Is this bad design?
There's nothing wrong with the code in your question. This
class Derived;
class Base {
virtual Derived f() = 0;
};
class Derived : public Base {
virtual Derived f() {return Derived();}
};
should compile just fine. However, callers of 'Base::f()' will need to have seen the definition of 'Derived`.
You could use a pointer (or a reference):
class Derived;
class Base {
virtual Derived *f() = 0;
};
class Derived : public Base {
};
But this is code smell to me. Why should anybody inheriting from this class need to know about another derived class? In fact, why should the base class be concerned with it's derivee's?
For your situation, you'll need to notice things that mgiht be a signal for bad design. Although it makes sense that your bounding box would derive from Shape, keep in mind, since Shape has a function that returns a bounding box, a bounding box will have a function that returns itself.
I'm not sure the best solution, but you could make BBox a separate class altogether, and perhaps give it a function akin to: Shape *as_shape(void) const, which would construct a class Box : public Shape with the same dimensions as the bounding box.
I still feel there is a better way, but I'm out of time for now, I'm sure someone else will think of a better solution.
Your notion about templates wasn't necessarily a bad one. What you describe is called the Curiously Recurring Template Pattern.
An example:
#include <iostream>
template <typename T>
struct Base
{
virtual T* foo() = 0;
};
struct Derived : Base<Derived>
{
virtual Derived* foo() { return this; }
};
Why not just do:
class Base {
virtual Base *f() = 0;
};
I'd go with returning a pointer to a Base, so that Base doesn't need to know about Derived or anything else that comes along later:
class Base {
virtual Base *f() = 0;
};
class Derived : public Base {
virtual Base *f();
};
Base *Derived::f() {
Derived *r = new Derived;
return r;
}
As others have pointed out, the code sample you have can be made to work, but that you probably mean to return a pointer to the base class from f().
In your elaboration, you mention that the bounding box is a subclass of shape, but there is a problem:
class Shape{
virtual Shape* getBoundingBox() = 0;
};
class Square: public Shape{
virtual Shape* getBoundingBox();
};
class BBox: public Shape{
virtual Shape* getBoundingBox(); // Whoops! What will BBox return?
};
Lets move some of the responsibilities around:
class Shape{
virtual void draw() = 0; // You can draw any shape
};
class BBox: public Shape{
virtual void draw(); // This is how a bounding box is drawn
};
class BoundedShape: public Shape{
virtual BBox* getBoundingBox() = 0; // Most shapes have a bounding box
};
class Square: public BoundedShape{
virtual void draw();
virtual BBox* getBoundingBox(); // This is how Square makes its bounding box
};
Your application will now probably need to hold collections of BoundedShape* and occasionally ask one for its BBox*.