2

I come from a Java background, where classes which extend (inherit from) other classes are often passed around as the super class. I was hoping to do something similar in C++, but I have never worked with C++ inheritance before. I currently have the following:

class Obstacle{
    double get_position(){return position;}
};

class Wall : public Obstacle {
    double get_normal(){return normal;}
};

Obstacles, in general, can be any shape, but Walls are rectangular and therefore have an easily designed normal, which would not be appropriate for most Obstacles to have. However, another class has an aggregated std::vector<Obstacle*> which contains all Obstacles. When iterating through these Obstacles and doing calculations, I need to do separate calculations for separate types of Obstacles (there's a get_type() function in the superclass as well). When I have a Wall, I'd like to be able to call get_normal(), but if I try static_cast<Wall>(current_obstacle)->get_normal() I get the compilation error: no matching function call to Wall(Obstacle*&). It also gives the same error if I use ((Wall)current_obstacle)->get_normal(). It seems as though I should make a Wall constructor which takes an Obstacle and creates a new Wall object, but these doesn't seem to make sense to me.

In Java, I can cast any class to its subclass using ((Wall)current_obstacle).get_normal(). Is this possible in C++ as well? Do I have to create a constructor? Thanks in advance. Sorry for my lack of understanding.

Teofrostus
  • 1,506
  • 4
  • 18
  • 29
  • This one deals with all the ways you can use to cast an instance: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used – didierc Feb 27 '15 at 01:48

2 Answers2

2
static_cast<Wall>(current_obstacle)->get_normal()

Try

static_cast<Wall*>(current_obstacle)->get_normal()
user207421
  • 305,947
  • 44
  • 307
  • 483
2

First, if current_obstacle is of type Obstacle*, then you should be casting it to Wall*. Currently you're trying to convert a pointer into a new object, which doesn't work.

Second, consider using dynamic_cast instead of static_cast. This will check whether the object pointed to is really of type Wall, and if not, will return a null pointer. static_cast does not check, and undefined behaviour (read: Bad Things) will happen if your Obstacle* doesn't really point to a Wall but you cast it and call a Wall member function. (Casting in Java always performs this check for you, as you know.)

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • 1
    The `dynamic_cast` behavior described only works for polymorphic types (those that have virtual member functions) – Ben Voigt Feb 27 '15 at 01:52
  • True enough. `Obstacle` should have its destructor declared virtual, given the way it's being used (i.e. polymorphically) – Brian Bi Feb 27 '15 at 01:53
  • Can you explain what a virtual destructor does? From my understanding, the `virtual` keyword is used to allow you to redefine a method in a subclass. Why would my destructor be virtual? I am not redefining it in my subclass. – Teofrostus Feb 27 '15 at 02:06
  • @Teofrostus Every class has a destructor which cleans up its members, and if you don't provide one the compiler does. – Quentin Feb 27 '15 at 02:13