templates vs switch - c++

I'm trying to find my ways in the C++ land and am increasingly confused by now. The toy application is a very basic OpenGL engine.
So here's the (I guess simple) problem:
I'd like to handle meshes of different vertex data, so I'd have e.g.
struct Vertex
{
Vector3f position;
}
struct VertexN : public Vertex
{
Vector3f normal;
}
Now I need a Mesh class, that holds the data and draws it.
I've tried something like this:
template<class T>
class Mesh
{
public:
Mesh();
~Mesh();
void load(const T * vertices, int num);
void draw();
protected:
T * vertices_;
};
The different vertices have to be loaded and drawn differently and this can be done with template specialization.
My problem is that I like to have another class that holds instances of Mesh objects, but templated class members are obviously not allowed.
The other solution I can think of is to hold pointers to the base struct Vertex in Mesh, pass an identifier for the Vertex type used and then use switch statements in load() and draw() to allow for the different implementations.
What is the best way to accomplish this?
Any help is greatly appreciated.

You can use inheritance and virtual functions. For example:
class MeshBase
{
public:
virtual ~MeshBase() { }
virtual void draw() = 0;
};
template <typename T>
class Mesh : public MeshBase
{
public:
virtual void draw() { }
// ...
};
With this approach, you can store pointers to the base class MeshBase in a container.
Ideally, you can use a pointer container, which will manage the pointers for you, or you can use a container of smart pointers (for example, a std::vector<std::shared_ptr<MeshBase> >, if your implementation includes shared_ptr; if not, it can be found in a number of places).
I would also recommend storing the vertices in a container in the Mesh class, rather than using manual dynamic allocation and memory management.

I recommend that you don't templatize your mesh class but make it capable of handling different types of vertex data. This is a common graphics problem and is addressed in DirectX with the notion of binding different "streams" of data together to draw geometry. In other words, your normals would be a different data stream than your position data. Then your mesh object becomes a container of multiple streams of data and would not be bound to a particular vertex format at compile time. I don't know OpenGL as well but I imagine there is a similar concept.
See: http://msdn.microsoft.com/en-us/library/bb147299(VS.85).aspx

#bshields has a point, you need to represent vertex data in the most efficient manner, which in the case of OpenGL are Vertex Buffer Objects (VBOs): http://www.opengl.org/wiki/Vertex_Buffer_Object
Given the guidelines exposed in the link above - which go in line with what #James McNellis says about not using inheritance for your Vertex types - and the fact that both loading and drawing will probably depend on the type of vertex and the kind of input (or output) I would suggest you to apply the Strategy pattern using static polymorphism, as outlined in the answer to this other question: template strategy pattern

Related

Downcast from a container of Base* to Derived* without explicit conversion

I am writing a scientific code which needs to create 3-dimensional cells, defined by a set of faces, which are defined by a set of vertices.
These 3 classes (Cell, Face, Vertex) are derived respectively from some generic geometry classes (Polyhedron, Polygon, Point) which implement some geometric routines like Polygon::CalculateArea().
The Face class adds to the Polygon class with additional data and functions required for the science, like Face::Interpolate(). I don't want to make these member functions virtual in the base class (Polygon).
Now, the problem. I initialize a Cell with a vector of pointers to Face, which is handled by the base class Polyhedron constructor, which upcasts the Face* to Polygon*:
Polyhedron::Polyhedron( std::initializer_list<Polygon*> polygons );
Later, I want to access the Face* stored in a Cell so that I can call Face::Interpolate(), but it has been stored as a Polygon* and thus has no member function Polygon::Interpolate(). I can downcast it manually back to a Face* which works, but is not very clean. The user of the code has to do something like:
Face * temp_face = (Face*)cell->GetFaces()[0]; // Could use static_cast
temp_face->Interpolate();
which is not obvious.
I want the interface to be transparent, so that this just works:
cell->GetFaces()[0]->Interpolate();
I can think of two or three ways to achieve this. I'm looking for a better solution or feedback of which of these is recommended:
In Cell::GetFaces() which currently just inherits from Polyhedron::GetPolygons() I could create a wrapper that copies the std::vector<Polygon*> to a new vector std::vector<Face*>. This seems sloppy to me, not easy to maintain, inefficient and prone to errors.
Instead of storing std::vector<Polygon*> I could store std::vector<std::shared_ptr<Polygon>>. From what I understand, these smart pointers retain type-awareness so that they can call the right destructor, but they might just store a reference to the destructor depending on implementation. I don't want to use shared_ptr for performance purposes -- I know they're good and friendly, but I'm creating millions of these Polygons and its easy to destroy them in the right place. I can't use unique_ptr easily because of the copy-constructor used in std::initializer_list constructors.
Template the whole Polyhedron class, replacing every instance of Polygon* with F* and checking that F is a base of Polygon:
template<typename F = Polygon>
typename std::enable_if<std::is_base_of<Polygon, F>::value, void>::type
class Polyhedron
and then inheriting from a parent with a given typename:
class Cell : public Polyhedron<Face>
This seems like the best method to me, since it has the least boilerplate and nothing exposed to the user; but it still feels messy, especially in the "real" case where there might be multiple types that would all have to be specified:
class Cell: public Polyhedron<Face,Vertex,type3,type4,type5,...>
Is there a a better way? Perhaps a means of retaining type in the original vector (or some other container)?
If not, which of the above methods is the best practice and why?
Edit:
Here's an abstracted view of the problem. The problem occurs when trying to run sumOfSomethingSpecific(). In my actual problem, that function is inside a derived class Derived_B, which is designed to work with Derived_A, but for the sake of the problem, it makes no difference.
class Base_A
{
public:
Base_A();
~Base_A();
// I don't want virtual doSomethingSpecific() here.
};
class Derived_A
{
public:
using Base_A::Base_A;
double doSomethingSpecific();
};
// I could template this whole class
// template <typename T>
// where T replaces Base_A
class B
{
public:
// This can be initialized with:
// std::vector<Derived_A*>
// which is what I want to do, but we lose info about doSomethingSpecific()
// even if I write a separate constructor its still stored as
// std::vector<Base_A*>
B(std::vector<Base_A*> v) : v(v) {};
~B();
double sumOfSomethingSpecific()
{
double sum = 0;
for(auto&& A : v) {
// Can't do this, A is a pointer of type Base_A*, but this is the abstraction that I want to achieve
sum += A->doSomethingSpecific();
// Could do this, but its ugly and error-prone
Derived_A* tempA = (Derived_A*)A;
sum += tempA->doSomethingSpecific();
}
return sum;
}
protected:
std::vector<Base_A*> v;
};
First most of issues you're facing here are not about programming, are about design.
... class with additional data and functions required for the science, like Face::Interpolate(). I don't want to make these member functions virtual in the base class (Polygon). ...
Well, don't do that, but then you have to realize that you're adding complexity to the code you need to implement such design desicion.
However, if every polygon can be "interpolated" then you should have a virtual function (or better yet a pure virtual function) in your Polygon class.
Said that, with the code as it is, in order to add transparency to the API you declare you get_* functions as:
void GetFaces(std::vector<Face *> &faces);
that way is clear for the user that he/she has to provide a reference to a vector of faces to get the result. Lets see how this change your code:
// Face * temp_face = (Face*)cell->GetFaces()[0]; // Could use static_cast
std::vector<Face *> temp_faces;
cell->GetFaces(temp_faces);
//temp_face->Interpolate();
temp_faces[0]->Interpolate();
This way the down-cast is performed implicitly.
About your question: Is there a a better way? Yes, redesign your classes.
About your example:
I will ask you to think a moment about this:
struct Base {};
struct Derived_A: Base { double doSomethingSpecific(); };
struct Derived_B: Base { double doSomethingSpecific(); };
int main()
{
std::vector<Base*> base_v = {/*suppose initialization here*/};
base_v[0]->doSomethingSpecific(); // Which function must be called here?
// Derived_A::doSomethingSpecific or
// Derived_B::doSomethingSpecific.
}
At some point you will have to tell wich type you want call the function on.
The level of abstraction you want, does not exists in C++. The compiler needs to know the type of an object in order to perform (compile) a call to one of its member functions.
Another approach you can try (I still recommend to redesign):
If you have the need of manipulating several distinct types in a uniform manner. Perhaps you want to take a look at Boot.Variant library.
I struggled with a similar problem in one of my projects. The solution I used was to give ownership of the actual objects to the most-derived class, give the base class a copy of the objects, and use a virtual function to keep the copy up-to-date as objects are added/removed:
class Polyhedron {
protected:
bool _polygons_valid = false;
std::vector<Polygon*> _polygons;
virtual void RebuildPolygons() = 0;
public:
std::vector<Polygon*>& GetPolygons()
{
if (!_polygons_valid) {
RebuildPolygons();
_polygons_valid = true;
}
return _polygons;
}
/*Call 'GetPolygons()' whenever you need access to the list of polygons in base class*/
};
class Cell: public Polyhedron {
private:
std::vector<Face*> _faces; //Remember to set _polygons_valid = false when modifying the _faces vector.
public:
Cell(std::initializer_list<Face*> faces):
_faces(faces) {}
//Reimplement RebuildPolygons()
void RebuildPolygons() override
{
_polygons.clear();
for (Face* face : _faces)
_polygons.push_back(face);
}
};
This design has the benefits of clear ownership (most-derived class is owner), and that copying and upcasting the vector of object pointers is done only when needed. The downside is that you have two copies of essentially the same thing; a vector of pointers to objects. The design is very flexible too, since any class derived from Polyhedron only has to implement the RebuildPolygons() function, using a vector of any type derived from Polygon.

Recursive Strategy Pattern

I am designing some classes for my project in C++ at the moment but I got a problem.
I want to create a camera class which holds all the needed values (e.g. transformation matrices) but the function which renders the camera should be exchangeable. This sounds like a usual case for the strategy pattern. Thus I created an interface which defines the render-function and gave the the camera class a pointer to this interface.
The problem is that the render function needs access to all the data in the camera class and therefore I gave this function a pointer to the camera class as a parameter. It looks like this:
#include "ICameraRender.h"
class Camera{
private:
ICameraRender* _cameraRender;
public:
Camera();
Camera(ICameraRender& cameraRender);
~Camera();
void renderCamera(){ _cameraRender->render(this); }
void setCameraRender(ICameraRender& cameraRender);
/..../
};
class ICameraRender{
public:
virtual ~ICameraRender(){
}
//Override me
virtual void render(Camera* camera) = 0;
};
This doesn't seem to be an elegant solution due to the liability to an infity loop (calling camera->renderCamera() in the render-function in ICameraRender). Is there a better solution to this problem?
Regards
EDIT:
I came up with another solution. Since the function which operates on the camera's data, only needs access to the data I thought I could split up the camera class itself. A class called Camera and CameraModel. The last one holds all the needed data and the first one does operations on it.
Therefore I just have to pass a pointer to CameraModel to my function:
class CameraModel{
private:
/...data.../
public:
/...setter and getter.../
};
class Camera{
private:
CameraModel* _cameraModel;
ICameraRender* _cameraRender;
public:
Camera();
Camera(ICameraRender& cameraRender);
~Camera();
void renderCamera(){ _cameraRender->render(_cameraModel); }
void setCameraRender(ICameraRender& cameraRender);
/..../
};
class ICameraRender{
public:
virtual ~ICameraRender(){
}
//Override me
virtual void render(CameraModel* cameraModel) = 0;
};
Now the render-function (which only calculates new values for the camera according to user input) does no longer have access to the renderCamera-function.
What do you think about this solution?
Regards Stan
You're right, it does seem like a bad design. :)
I don't see why a camera render needs access to a camera. I'm sure you can pass something else as parameter. The render doesn't need access to all the camera members, so you can just pass the ones it needs (and, if there's a lot of them, wrap them in a structure CameraConfig or something like that).
If the different renders need different parameters, you can make a separate hierarchy with ICameraConfig.
This is probably a great time to use Policy-based design to implement the strategy pattern, especially since you're using C++ and you're probably targeting a compiler older than 2002. (Since C++'s templating mechanism is so awesome, we can get the strategy pattern for free this way!)
First: Make your class accept the strategy/policy class (in this case, your ICameraRenderer) at a template parameter. Then, specify that you are using a certain method from that template parameter. Make calls to that method in the camera class...
Then implement your strategies as a plain old class with a render() method!
This will look something like this:
class Camera<RenderStrategy>{
using RenderStrategy::render;
/// bla bla bla
public:
void renderCamera(){ render(cameraModel); }
};
class SpiffyRender{
public:
void render(CameraModel orWhateverTheParameterIs){ // some implementation goes somewhere }
};
Whenever you want to make a camera that uses one of those policy/strategies:
// the syntax will be a bit different, my C++ chops are rusty;
// in general: you'll construct a camera object, passing in the strategy to the template parameter
auto SpiffyCamera = new Camera<SpiffyRender>();
(Since your renderer strategy doesn't have any state, that makes this approach even more favorable)
If you are changing your renderer all the time, then this pattern / approach becomes less favorable... but if you have a camera that always renders the same way, this is a slightly nicer approach. If your renderer has state, you can still use this method; but you'll want a reference to the instance inside the class, and you won't use the Using:: statement. (In general, with this, you write less boilerplate, don't need to make any assignments or allocations at runtime, and the compiler works for you)
For more about this,see: http://en.wikipedia.org/wiki/Policy-based_design
Or read Modern C++ Design... it's a great read, anyways! http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315
As an unrelated aside: You may want to look into some of the goodness that C++x11 gives you. It'll really clean up your code and make it safer. (Especially the shared/unique/etc ptr classes.)

About implementation of abstract/concrete graphs in C++

I am writing a program that works with graphs. I am dealing with two types of graphs : "abstract graphs", which consist in abstract vertices with edges, and "planar graphs", in which the vertices have coordinates x,y in the plane (actually I am working with a complex affix z but it does not matter).
I have elected to write an (abstract) Vertex class and a derived class Planar_Vertex as follows in my Vertex.h file - this is not precisely my code, I made it slightly simpler and "translated" it from French ;)
class Vertex
{
public:
Vertex();
int get_label();
void set_label(int label);
void add_neighbor(int label);
bool is_neighbor(int label);
// etc
protected:
int _label;
std::vector<int> _list_neighbors;
};
class Planar_Vertex : public Vertex
{
complex<double> _affix;
public:
Planar_Vertex();
Planar_Vertex(Vertex& V, complex<double> affix);
complex<double> get_affix();
void set_affix(complex<double> affix);
};
Here's my main question. I would like my Planar_Vertex(Vertex& V, complex affix) constructor to have the following effects : 1. Output a Planar_Vertex whose label and list of neighbors are the same as V, and whose affix is given. So far, easy. 2. I would like V to be precisely the abstract Vertex underlying this new object. In other words, if in my main.cpp file I wrote, say,
Vertex V1;
...
Planar_Vertex V2(V1,z)
then I would like that a use of set_label() on V2 will also affect V1 (for example). The way I see it is, in this constructor, I would like to say something like: make the address of V (in memory) the same as that of the Planar_Vertex constructed (and free the memory previously allocated to V). Apparently it is not possible to change the location of a variable in memory though, so I don't know what to do. I am relatively new to C++ and I'm getting lost reading about placement new, std::move, rvalues etc. Does anybody see how to do what I want?
[Edit : To summarize, I want to be able to build an object of the derived class on top of an object of the base class that has already been built.]
Okay, now since I told you guys that much about my implementation of graphs, I thought I'd tell you the rest so you can give me your opinion about it, I hope you don't mind. Obviously you don't have to read the following, if you know the answer to my first question that'd be cool already. So as I told you we're dealing with "abstract graphs", which will consist in abstract vertices, and planar graphs, which consist in planar vertices.
Here's what my Graph.h file looks like:
class Graph
{
public:
Graph();
virtual ~Graph();
virtual std::vector<Vertex*> get_list_vertices();
void add_edge(int label1, int label2);
virtual void add_vertex(Vertex&);
// etc
};
class Abstract_Graph : public Graph
{
std::vector<Vertex*> _list_vertices;
public:
Abstract_Graph();
~Abstract_Graph();
std::vector<Vertex*> get_list_vertices();
void add_vertex(Vertex& V);
// etc
};
class Planar_Graph : public Graph
{
std::vector<Planar_Vertex*> _list_planar_vertices;
public:
Planar_Graph();
~Planar_Graph();
std::vector<Vertex*> get_list_vertices();
std::vector<Planar_Vertex*> get_list_planar_vertices();
void add_vertex(Planar_Vertex& V);
// etc
};
My idea is that the base class Graph will never be instanciated, but I will be able to implement "abstract graph operations" as functions of this base class and they will work on both Abstract_Graph and Planar_Graph objects. This is made possible thanks to the purely virtual function get_list_vertices. Is this a reasonable way to do things? What would you have done?
Thank you very much for for answers in advance.
You can keep a reference (or a pointer) to a Vertex object in your Planar_Vertex class to do what you want if I understood you.
Cut down demo:
#include <iostream>
struct Vertex {
int value;
};
struct Planar_Vertex: public Vertex {
Vertex& vr;
Planar_Vertex(Vertex& v): vr(v) {}
};
int main()
{
Vertex v;
v.value = 1;
std::cout << v.value << std::endl;
Planar_Vertex p = Planar_Vertex(v);
p.vr.value = 2;
std::cout << v.value << std::endl;
}
If you use a reference, it must be initialized in the constructor initialization list. If you use a pointer, you have more flexibility in how you initialize it, but have to worry about null pointers everywhere.
In both cases, you're responsible for making sure that the Vertex outlives the Planar_Vertex.
(Another option is to have a plain Vertex (not a reference or pointer) as a member of Planar_Vertex – you initialize it via Planar_Vertex's constructor, and use it wherever you need. This takes care of the lifetime requirements, but might not be possible in your code.)
For your second part, I don't see anything fundamentally wrong, but it's hard to have an opinion just with what you posted. Inheritance is one way to do this, another would be to use templates. Which one is more appropriate depends on the exact requirements (and your familiarity with both these concepts).

template <typename T> perculating all through the code

I templatized a class earlier and as a result of this templatization, all classes that received objects of this newly templated type require templating as well, even where the templatization is completely irrelevant.
So:
class Shape is the base class for class Sphere, Cube, Model
Each Shape contains a Mesh
Mesh has now been templatized to allow for basically the VertexBuffer to have a parameterized type:
So:
template <typename T> struct Mesh
{
VertexBuffer<T> verts ; // Mesh needs to be templated to allow
// the vertex buffer to be templated as well
} ;
So now the class that contains the Mesh (base class Shape) needs to be templated as well:
template <typename T> class Shape
{
Mesh<T>* mesh ;
} ;
And now, all the methods anywhere in the code need to be templated as well, even where that templatization in no way affects the code (ie that code has no business with the vertex type of the Mesh member)
So for example, the octree node:
// An octree node
template <typename T> struct ONode // but this class doesn't really benefit
// from templatization
{
AABB bounds ;
ONode* parent ; // facilitate movement thru the tree
ONode* children[8]; // cells, octants, cubelets
Shape<T>* objects ; // for the purposes of the Octree,
// But ALL SHAPES BEHAVE THE SAME. <T> serves no purpose
This is a really nasty artifact and I'm not sure how to stop the perculation of templatization at an earlier point, or if templatization was a correct choice now that I see how much needs to be templatized.
I would suggest you create a non-templated base class for Mesh (or VertexBuffer, whichever makes the most sense) that exposes the functionality that doesn't depend on the template, and use that in other places. For example:
class MeshBase
{
// Functionality that doesn't depend on the template type.
};
template<typename T>
class Mesh : public MeshBase
{
// Functionality that does depend on the template type.
};
This does mean that you may more frequently need to deal with dynamically allocated values of this type and pass them around as pointers, but some judicious use of smart pointers should alleviate that burden.
In general, there is a certain friction between using object oriented principles and generic programming principles, some of which you've discovered here. Whenever this happens, you essentially need a class that can hold the value of multiple generic types and models the common behavior, without the consumer needing to know the templated type. Sometimes, this can be done even if the types have no common base. This technique is called type erasure and this article by Thomas Becker provides some insight into this matter.

C++ inheritance question

I have the following problem in application architecture and am willing to solve it (sorry for a lot of text).
I am building a game engine prototype and I have base abstract class AbstractRenderer (I will use C++ syntax, but still the problem is general).
Assume there are some derived implementations of this renderer, let's say DirectxRenderer and OpenglRenderer.
Now, let's say that only one of these renderers (let's stick to DirectX-based) has a member called IDirect3D9Device* m_device; Obviously at this point everything is fine - m_device is used internally in DirectxRenderer and shouldn't be exposed in the abstract AbstractRenderer superclass.
I also add some abstract rendering interface, for instance IRenderable. It means simply one pure virtual method virtual void Render(AbstractRenderer* renderer) const = 0;
And this is the place where some problems start. Assume I am modelling some scene, so, this scene will probably have some geometrical objects in it.
I create abstract superclass AbstractGeometricalObject and derived DirectX-based implementation DirectxGeometricalObject. The second one would be responsible for storing pointers to DirectX-specific vertex & index buffers.
Now - the problem.
AbstractGeometricalObject should obviously derive the IRenderable interface, because it's renderable in logical terms.
If I derive my DirectxGeometricalObject from AbstractGeometricalObject, the first one should have virtual void Render(AbstractRenderer* renderer) const { ... } method in it, and that Abstract... stuff brings some troubles.
See the code for better explanation:
And for now my classes look the following way:
class AbstractGeometricalObject : public IRenderable {
virtual void Render(AbstractRenderer* renderer) const { ... }
};
class DirectxGeometricalObject : public AbstractGeometricalObject {
virtual void Render(AbstractRenderer* renderer) const {
// I think it's ok to assume that in 99 / 100 cases the renderer
// would be a valid DirectxRenderer object
// Assume that rendering a DirectxGeometricalObject requires
// the renderer to be a DirectxRenderer, but not an AbstractRenderer
// (it could utilize some DX-specific settings, class members, etc
// This means that I would have to ***downcast*** here and this seems really
// bad to me, because it means that this architecture sucks
renderer = dynamic_cast<DirectxRenderer*>(renderer);
// Use the DirectX capabilities, that's can't be taken out
// to the AbstractRenderer superclass
renderer.DirectxSpecificFoo(...);
}
I know I'm probably worrying too much, but this downcast in such a simple case means that I could be forced to make lots of downcasts if my application grows.
Definitely, I would like to avoid this, so please, could you advice me something better in design terms / point out my errors.
Thank you
This might be a situation where the template pattern (not to be confused with C++ templates) comes in handy. The public Render in the abstract class should be non-virtual, but have it call a private virtual function (e.g. DoRender). Then in the derived classes, you override DoRender instead.
Here's an article that goes into great depth describing the use of template pattern with private virtual functions.
Edit:
I started to put together an example of what I meant, and it seems like there's actually a broader flaw in the architecture. Your use of AbstractRenderer is somewhat frivolous since you're forcing each geometricalobject to be intimately aware of a particular renderer type.
Either the renderer should be able to work off the public methods of Renderables, or Renderables should be able to work off the public methods of the Renderer. Or perhaps you can give the concrete renderers a Renderable factory if there really needs to be such an intimate connection. I'm sure there are some other patterns that would fit well, too.
I don't see what your code wants to achieve. You derive Renderable objects to DirectXRenderables and OpenGLRenderables and then provide OpenGL or DirectX functionality in something derived from Renderer. A specific thing uses another specific thing so to speak.
It would seem much more reasonable to identify general rendering functions, make them pure virtual members of your abstract renderer and implement them in DirectXRenderer and OpenGLRenderer. Then a IRenderable would have a member function draw roughly like this:
void draw(const AbstractRenderer& r) {
//general stuff
r.drawLine(...);
//only possible on directX
if(DirectxRenderer rx = dynamic_cast<DirectxRenderer*>(r)) {
//...
} else {
//throw exception or do fallback rendering in case we use something else
}
}
Using templates, you could split the IRendable into two classes, one for each of the two renderer types. This is probably not the best answer, but it does avoid the need for the dynamic cast:
template <typename RendererType>
struct IRenderable {
virtual void Render(RendererType* renderer) const = 0;
}
template <typename RendererType>
class AbstractGeometricalObject : public IRenderable<RendererType> {
virtual void Render(RendererType* renderer) const { ... }
};
class DirectxGeometricalObject : public AbstractGeometricalObject<DirectxRenderer> {
// this class will now require a void Render(DirectxRenderer* renderer)
}
Use a setter to set the renderer var and cast it to the proper type in that one place.
See if the Bridge design pattern helps you: "Decouple an abstraction from its implementation so that the two can vary independently." In your example, AbstractGeometricalObject would point to an implementation, a pure virtual interface with platform-specific subclasses. The tricky part is taking the time to discover that interface.
Let's distance from compilers and consider theory. If DirectxGeometricalObject::Render expects DirectxRenderer as parameter and not any AbstractRenderer, then some other OtherGeometricalObject::Render will probably expect OtherRenderer object as parameter.
So, different implementations of AbstractGeometricalObject have different signatures of their Render methods. If they are different, then there is no purpose in defining the virtual AbstractGeometricalObject::Render.
If you declare AbstractGeometricalObject::Render(AbstractRenderer*), then you should be able to pass any renderer to any geometrical object. In your case, you can't because dynamic_cast would fail.