Reputation: 1011
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
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
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
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
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