Thread: dynamic_cast question

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    9

    dynamic_cast question

    My compiler is outputting the following error: "cast from base to derived requires dynamic_cast or static_cast" even though im declaring a dynamic cast about 2 lines before. Here's my basic setup
    Code:
    class Shape
    {
     public:
        Shape(){};
        virtual ~Shape(){};
    };
    //above format for the following classes
    
    class Rectangle:public Shape
    class Square:public Rectangle
    
    class Triangle:public Shape
    class Equilateral:public Triangle
    
    class Unrelated:
    {
    public:
        Unrelated(){};
        ~Unrelated(){};
    
        Triangle * atriangle;
        std::vector<Shape*> vectorofshapes;
        void InputShape(Shape * pShape){vectorofshapes.push_back(pShape);}
    
        void FetchShape(Shape * ppShape)
        {
            Triangle * testtriangle = dynamic_cast<Triangle*>(ppshape);
            if (testtriangle != NULL)
                atriangle = ppshape;
        }
    }
    
    int main()
    {
        Unrelated  object;
        Triangle * triangle[5];
    
        for ( i = 0; i < 4; i++ )
            triangle[i] = new Equilateral;
    
        object.InputShape(triangle[0]);
        object.FetchShape( object.vectorofshapes.at(0) );
    
        return 0;
    }
    "error: '=' cannot convert from 'Shape *' to 'Triangle *' Cast from base to derived requires dynamic_cast or static_cast"

    On a side note the main reason for my equilateral and square classes is so that i can produce copies of specific types of my triangle and rectangle classes during runtime...they don't have any different properties, just more specific. Like in the above example, let's say a constructor for Triangle was Triangle(int a,b,c){angleA = a, angleB = b, angleC = c}, the only difference between Triangle and Equilateral would be that Equilateral's constructor is Equilateral(){}:Triangle(60,60,60); So if there is a more efficient way to do this other than creating whole new derived classes that would definately be preferred.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    atriangle = ppshape;
    should be
    atriangle = testtriangle ;
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    9
    thx, that worked and actually makes alot more sense. Strangly, the book im reading (teach yourself c++ in 21 days (lol yea right)) says otherwise. Also, does anyone know why this runs fine on VC++ Express, but when i try to run this w/ borland compiler it says my base class isnt a polymorphic class type? I thought to be a polymorphic class it just had to contain a virtual function.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    hmm... could you give the code that you tested with?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Some compilers require you to turn on options to use dynamic_cast, make sure any such options are on in Borland.

    Also note that while dynamic_cast does have its uses, it is often a sign of poor design. Consider looking at your design and making sure it models a true is-a relationship.
    Last edited by Daved; 01-01-2007 at 02:01 PM.

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    9
    RTTI is enabled in borland and I cant find anything else that seems relevant casting or specifically dynamic_cast in the help manual or on their website. The only reason I'm using dynamic_cast here is because I need a container (in this case a vector) to hold all derived types of Shape, but when I try to access them in the vector, they have been converted to the base class type, and so i use dynamic_cast to just undo what the vector did. Is this not a correct use of it? I suppose I could make an overloaded function and a different vector for each derived type, but wouldn't that kind of defeat the purpose of polymorphism?

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Yes, a separate vector for each would defeat the purpose of polymorphism, but casting the base class pointer with dynamic_cast defeats the purpose in the same way. The power of dynamic polymorphism is that when you use the base class pointers that are stored in your vector, you don't care what the actual derived type is. You just use the interface provided by the base class and let virtual function calls do the work of executing the correct derived class code.

    What you want to do is provide an interface in the base class that is consistent for the type that the base class represents. Then, the derived types should implement that interface in a specialized way that matches what they are. If the derived class interface differs from the base class interface, then it might not truly model an is-a relationship.

    An example is a square and a rectangle. If you have a base class called rectangle that includes in its interface a widen function that is intended to stretch the rectangle without affecting its height, then you should not really be deriving square from rectangle because in this case a square is not a rectangle. A square cannot be widened without affecting its height. If however, the rectangle interface does not violate any rules of the square, then it might be appropriate to derive square from rectangle (for example to implement an optimized algorithm of some sort).

    In the example code provided, it is hard to say whether an inheritance relationship is appropriate or not. There might be another way to model the situation.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Posts
    9
    hrmm...my base class and derived classes don't conflict at all, the problem I'm having is that my two derived classes are different from eachother, and so they have different functions. So, lets say Triangle has a PythagoreanTheorem() function, and this is obviously not going to be in my rectangle class (not exactly the best example since a rectangle can be divided into 2 triangles, but let's pretend it can't for the time being ). How could I access that function from an object once its been put into my vector without having to move the function up into my base class?(which, as i understand it, is a big no-no)

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    When do you need access to that function? In other words, what are you doing that requires a call to that function? It may be possible to abstract that part of the code into a virtual function in the base class.

    For example, let's say that you call PythagoreanTheorem to verify that the dimensions of the triangle are correct. Maybe your Rectangle class also has a function that verifies that its dimensions are correct (opposing sides are equal). Then you might create a virtual base class function called VerifyDimensions and let the derived classes override that with the Triangle's version using PythagoreanTheorem() and the Rectangle's version using it's own specific functions.

    If the code that needs to call PythagoreanTheorem is not generic at all, then maybe you should not be storing the shapes as base class pointers, or at least there should be a separate method to retrieve only the Triangle objects to call your function from.

  10. #10
    Registered User
    Join Date
    Dec 2006
    Posts
    9
    Ok, well here's my situation. My base class is Item, and the derived classes (for now) are armor and weapons, although i do plan on adding other types(potions,scrolls,etc). The unrelated class is entity, the vector is the entity's inventory that holds pointers to instances of items(i know there's probably a better container for this but the book I bought on STL doesnt arrive for another couple weeks). Then, i have a variable for each equipable item slot that holds a pointer to an object of that specific derived type i.e a variable for helm slot, another for hands etc, but without the dynamic cast they would hold pointers to the base class (I'm not sure I like this, it seems less secure, although would be kind of funny to go around bashing guys on the head with plate boots ).

    The problem comes when these.....and I just realized that instead of using the vector to reference items i could just use the items themselves, have a function that checks if theyre in the inventory, and overload the function in my entity class to take both types. How come it seems like the simple solutions always evade me lol. Thanks for making me think about the problem though instead of trying to use a band-aid solution.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  2. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  3. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM