Nadav Peled
Nadav Peled

Reputation: 1011

C++ how to check if two clsses are from the same object

Encountered this issue while studying for a test, would appericiate a brief explenation.
If I have a class Object and another one : class Point : public Object
Now, If I get Object& O1 and Object& O2 , but Object can be Point too...
So my main question is how can I check if both of them are Point Because I need to access a field that Object doesnt have

Here are the two classes :

Class Object {
public :
some functions
};

Class Point : Public Object {
double x;
double y;
public:
same functions different implementation
};

I wanna access x,y but I need to make sure its a Point first.

Thanks in advance

Upvotes: 1

Views: 2097

Answers (4)

Escualo
Escualo

Reputation: 42082

You can rely on the type information provided by the C++ Standard Library. The following example has been extracted from cppreference.com:

#include <iostream>
#include <typeinfo>
#include <string>
#include <utility>

class person
{
  public:

   person(std::string&& n) : _name(n) {}
   virtual const std::string& name() const{ return _name; }

  private:

    std::string _name;
};

class employee : public person
{
   public:

     employee(std::string&& n, std::string&& p) :
         person(std::move(n)), _profession(std::move(p)) {}

     const std::string& profession() const { return _profession; }

   private:

     std::string _profession;
};

void somefunc(const person& p)
{
   if(typeid(employee) == typeid(p))
   {
      std::cout << p.name() << " is an employee ";
      auto& emp = dynamic_cast<const employee&>(p);
      std::cout << "who works in " << emp.profession() << '\n';
   }
}

int main()
{
   employee paul("Paul","Economics");
   somefunc(paul);
}

Upvotes: 1

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

You can use dynamic_cast

Object &o = ...;
if(Point *p = dynamic_cast<Point*>(&o)) {
  // ...
}

If the dynamic type of o is a Point or derives from it, the code within the if will be executed with p being readily available (the static type of o is Object).

If you already know that it is a Point, you can use references

Point &p = dynamic_cast<Point&>(o);
// ...

For this to work, there must at least be one virtual function (if only the destructor) in Object.

Upvotes: 7

Mats Petersson
Mats Petersson

Reputation: 129374

Generally, if you "need" to know this, you are doing it wrong. There are a few exceptions, but as a rule, you should not need to know which type of object you are "using". Your functions that are different should be declared as virtual, so that the code that is doing something with an Object can just call the relevant function in Point if the object is a Point type object.

If you want to access x and y, your should be doing that indirectly through a virtual function that performs whatever action needs to be done on x and y. If you really need to touch x and y when you only have (a reference or pointer to) an Object, you are simply at the wrong level.

Upvotes: 3

HopAlongPolly
HopAlongPolly

Reputation: 1443

It may be sloppy but if you have a pointer or reference to an object you can always invoke a dynamic_cast. if the pointer is returned as nullptr then you know your object is not a derived class of the desired object.

class CBase { 
      virtual void dummy(){}
};
class CDerived: public CBase {
    int a;
};

int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}

Upvotes: 0

Related Questions