Archived

This topic is now archived and is closed to further replies.

gimp

Can't Dynamic_Cast a polymorphic type?

Recommended Posts

class COpenGLRenderer : public CRenderer When I obtain an opengl object from my DLL I''d like to ensure I have recived ''something'' dericed from CRenderer. I tried to do it like this: Renderer = dynamic_cast(Component->Get()); (Where component is just a generic libaray and class loader) NOTE : I turned on RTTI on my opengl renderer.dll. The problem is that the compiler doesn''t think dynamic_cast and CRenderer should be friends possibly due to some pure virtual methods on CRenderer that are defined on COpenGLRenderer. The clincher is that my EXE doesn;t know anything about whats in the DLL''s, except that it should be geting back some kind of renderer. Do I need to use my own form of RTTI to get past this? Many thanks Chris

Share this post


Link to post
Share on other sites
From the error you are saying, it seems like you have not overriden all the PURE virtual fonction in your openglRenderer

Edited by - Gorg on April 23, 2001 11:58:53 AM

Share this post


Link to post
Share on other sites
No, I don't think you need to write your own version of RTTI. RTTI was included in C++ because many developers were making their own versions, which, of course, were incompatible with each other's code. dynamic_cast is very powerful. It can cast up, down, and across class hierarchies, and even work with multiple inheritance if you resolve the ambiguities.

What is the exact error message? What is the return type of Component->Get()?

Edited by - null_pointer on April 23, 2001 11:14:26 AM

Share this post


Link to post
Share on other sites
Thanks guys.

Component->Get() returns a pointer to a derived object. So in this case a COpenGLRenderer object.



Actually thats wrong, the object in memory is a COpenGLRenderer object and thats what the pointer points to but that call returns a generic IInterface* which. CRenderer derives from IInterface. So it''s two levels down(if you drew it on paper) from COpenglRenderer.

So I guess I want to upcast the IInterface to CRenderer and call a pure virtual function on CRenderer that is implemented in COpenGLRenderer.

The goal is for my code to never know anything about COpenGLRenderer, it just knows about CRenderer.

Thanks

Chris

Share this post


Link to post
Share on other sites
I think I may have found the problem. Try the following console app. The code in renderer.cpp is overly complicated; it simply forces the compiler to check the validity of the cast at run-time.


// interface.h
#pragma once

class interface { public: virtual ~interface() {} };

// component.h
#pragma once
#include "interface.h"

class component : public interface
{
public:
virtual void function() = 0;
};

// renderer.h
#pragma once

class interface* get();

// renderer.cpp
#include "StdAfx.h"
#include "component.h"
#include "renderer.h"
#include <iostream>
#include <ctime>
#include <cstdlib>

using std::cout;
using std::endl;

class gl : public component
{
public:
virtual void function() { cout << "gl::function was called" << endl; }
} gl_renderer;

class dx : public component
{
virtual void function() { cout << "dx::function was called" << endl; }
} dx_renderer;

interface* get()
{
srand(time(0));

int x = rand() % 2;

switch( x )
{
case 0: return &gl_renderer;
case 1: return &dx_renderer;

default: return 0;
}
}

// Dynamic casting.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "component.h"
#include "renderer.h"

int main(int argc, char* argv[])
{
interface* p = get();
dynamic_cast<component*>(p)->function();

return 0;
}



The get function simply returns a random renderer. The dynamic_cast goes from interface to component; note that interface doesn''t have a "virtual void function()", so the cast is obviously working.

Now change the interface class to this:


class interface {};



And watch the fireworks.

Share this post


Link to post
Share on other sites
Thanks again null... I puled apart your example and found what I was doing wrong... Another greate answer...


You should write a book...

Share this post


Link to post
Share on other sites