Consider two classes, PersonClass and LawyerClass.

If LawyerClass derives from PersonClass, you can create a PersonClass* as a LawyerClass, like

PersonClass* Person = new LawyerClass;

then you can convert it to a LawyerClass* with

LawyerClass* Lawyer = static_cast<LawyerClass*>(Person);

However, if you don't know that the person should be a lawyer to start with:

PersonClass* Person = new PersonClass;

is there any hope of transforming him into a lawyer? This:

LawyerClass* Lawyer = static_cast<LawyerClass*>(Person);

does not work - Lawyer is invalid after the cast.

The reason I need to do this is that there is a library I am using that has a reader class, say ImageReader that returns an Image. Then I have created a subclass called FancyImage and I want to convert the output from the reader (Image) to my FancyImage but I cannot control what the reader outputs.

Any thoughts?

Thanks,

Dave

Recommended Answers

All 5 Replies

isnt that what Parametric Polymorphism is for?

e.g i used that in chess so that i coded for a generic piece, but each piece had a custom move method (using virtual functions).

Think about the relationship described by inheritance, and why what you're doing isn't possible;

class Vehicle {};

class Bike : public Vehicle {};
class Car : public Vehicle {};
class Truck : public Vehicle {};

The relationship can be described as "IS A"; in other words, Car IS A Vehicle and Truck IS A Vehicle. But the reverse is not true - Vehicle is not a Truck, and Vehicle is not a Car; Vehicle is just a Vehicle.

A Vehicle could be used as a starting point to create a Truck, Car or Bike, maybe, since a Vehicle contains some of the information about those derived classes, but that information is incomplete. You can't change the type of an object, so you will need to create a new one instead, using the Vehicle object as the derived object's constructor information

class Vehicle {};

class Bike : public Vehicle 
{
public:
    Bike(const Vehicle& v) : Vehicle(v) {}
};
class Car : public Vehicle
{
public:
    Car(const Vehicle& v) : Vehicle(v) {}
};
class Truck : public Vehicle
{
public:
    Truck(const Vehicle& v) : Vehicle(v) {}
};

>Think about the relationship described by inheritance,
>and why what you're doing isn't possible

And yet it is possible. What the OP wants to do is called downcasting. It's not recommended for the obvious reasons, but it's a feature that C++ supports using dynamic_cast because it's sometimes necessary:

#include <iostream>
#include <string>

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

class LawyerClass: public PersonClass {
public:
  virtual ~LawyerClass() {}
};

void test ( PersonClass *p )
{
  if ( dynamic_cast<LawyerClass*> ( p ) != 0 )
    std::cout<<"It's a lawyer! Run!\n";
  else
    std::cout<<"It's a person!\n";
}

int main()
{
  PersonClass *p = new PersonClass();
  PersonClass *q = new LawyerClass();

  test ( p );
  test ( q );

  delete p;
  delete q;
}

What the OP wants to do is called downcasting. It's not recommended for the obvious reasons, but it's a feature that C++ supports using dynamic_cast because it's sometimes necessary:

Yes, but the example shown in the OP was attempting to access a Base object via a Derived pointer

PersonClass* Person = new PersonClass;
LawyerClass* Lawyer = static_cast<LawyerClass*>(Person);

Unless I've misread the OP's intentions their goal is to change the type of the object itself at runtime (i.e. they want to extend it to become a valid LawyerClass object instead of PersonClass); Since that most likely means extending the size of the PersonClass object, I can't see any way that could be done safely without creating a new LawyerClass object elsewhere.

I ended up having to create a LawyerClass object and then copying in the data from the PersonClass. Thanks for the discussion/help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.