473,765 Members | 2,010 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to judge if two objects have the same type?

Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?

I appreciate your help.

Shuisheng

Nov 30 '06 #1
15 7624

"shuisheng дµÀ£º
"
Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?

I appreciate your help.

Shuisheng
Did you consider about RTTI?

Nov 30 '06 #2
shuisheng wrote:
Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?
Start with legal syntax.

C++ has type information built right into the syntax. What you
wrote there is not legal and is thus not a reasonable question.
It cannot be answered any more than one can answer any
non-sensical question.

You might ask something like (given your example classes)
if you had a function with prototype as such:

void myFunc(Obj *pObj);

then in the body of the function how could you tell what the
actual type of the object passed in was?

Or you could write something like this (psuedo code only):

if(complicated stuff that cannot always be predicted at compile time)
Obj *pA = new Shape;
else
Obj *pA = new Color;

How can you determine the type of the object pointed at by pA
after this runs?

There are two layers of answer: The first is "run time type info."
Look it up.

The second layer is, most of the time you shouldn't be asking
this question even in this situation. If you've got an inheritance,
the child class is supposed to be able to substitute for
the parent class. Look up Liskov substitution. A well written
C++ inheritance will work properly regardless of the type of
object that pA actually points to, provided it is public inheritance
from the type Obj. If you think you need this info, you should
be considering a rewrite of the classes involved so that you
don't need it.
Socks

Nov 30 '06 #3
if( typeof(pA) == typeof(pB ) { /* the same */ }

or something like that :)
Puppet_Sock wrote:
shuisheng wrote:
Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?

Start with legal syntax.

C++ has type information built right into the syntax. What you
wrote there is not legal and is thus not a reasonable question.
It cannot be answered any more than one can answer any
non-sensical question.

You might ask something like (given your example classes)
if you had a function with prototype as such:

void myFunc(Obj *pObj);

then in the body of the function how could you tell what the
actual type of the object passed in was?

Or you could write something like this (psuedo code only):

if(complicated stuff that cannot always be predicted at compile time)
Obj *pA = new Shape;
else
Obj *pA = new Color;

How can you determine the type of the object pointed at by pA
after this runs?

There are two layers of answer: The first is "run time type info."
Look it up.

The second layer is, most of the time you shouldn't be asking
this question even in this situation. If you've got an inheritance,
the child class is supposed to be able to substitute for
the parent class. Look up Liskov substitution. A well written
C++ inheritance will work properly regardless of the type of
object that pA actually points to, provided it is public inheritance
from the type Obj. If you think you need this info, you should
be considering a rewrite of the classes involved so that you
don't need it.
Socks
Nov 30 '06 #4

shuisheng wrote:
Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?

I appreciate your help.

Shuisheng
First off, having everything derive from Obj is not a good idea. Shape
should be an abstract class here and color should reside in a distinct
inheritance hierarchy. Otherwise you will get headaches having to
manage what is what. Unlike Java, Obj base is not needed since C++ has
a much more resilient and powerful system called < templates >.

Lets face it, a C++ programmer should only need to detect type, as you
are attempting here, only in the rarest of occasions. Consider what
happens if you write a class that takes an Obj reference as a
parameter. How are you going to enforce what Obj is legally
accepteable? Using typeid? Thats downright wrong, unsafe and
complicated.
C++ needs not detect what type a given instance "belongs to". Thats
because an instance is an object. Its self aware. It already knows what
it can and cannot do. Thats the basis of OO design. making everything
an Obj defeats the purpose.

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <typeinfo>

class Shape { };
class Triangle : public Shape { };

// will only accept a Shape or derivative
void check_type(Shap e& r_shape)
{
std::cout << "shape's type = ";
std::cout << typeid(r_shape) .name();
std::cout << std::endl;
}

int main()
{
boost::shared_p tr< Shape sp_shape(new Triangle);
check_type( *sp_shape );
}

/*
shape's type = Triangle
*/

Nov 30 '06 #5
mv*******@gmail .com wrote:
if( typeof(pA) == typeof(pB ) { /* the same */ }

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.c om/c++-faq-lite/how-to-post.html>
Nov 30 '06 #6

Default User wrote in message ...
>mv*******@gmai l.com wrote:
>if( typeof(pA) == typeof(pB ) { /* the same */ }


Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.c om/c++-faq-lite/how-to-post.html>
I was just thinking about a reply for such people:

" YOU IDIOT!! Do you realise you just screwed up a perfectly good thread!!
Now we'll have to reformat it and start over!! FAQ YOU!!"

"Please don't top-post" just isn't working since Google screwed up in a Gates
way.

--
Bob <GR
POVrookie
Dec 1 '06 #7

Salt_Peter wrote:
Unlike Java, Obj base is not needed since C++ has
a much more resilient and powerful system called templates<>.
I want to notice, that code, written with templates<>, is _compile time
template_ and can not replace (must just works together), of course,
any _runtime templates_.

In order to write class for _runtime template_ you must define a class
with the help of base class interface inheritance (public inheritance).
In order to use any function as _runtime template_, you must use for
all its runtime objects (variables) only pointers or references of its
public base class.

Of course, you must use inheritance _only_ for oo design necessity.
Using typeid? Thats downright wrong, unsafe and complicated.
One can do like this:
void foo(Obj& obj)
{
Shape* sh=dynamic_cast <Shape*>(&obj );
if(sh){ /* Shape-specific code */ }

Color* co=dynamic_cast <Color*>(&obj );
if(co){ /* Color-specific code */ }
}
C++ needs not detect what type a given instance "belongs to". Thats
because an instance is an object. Its self aware. It already knows what
it can and cannot do. Thats the basis of OO design. making everything
an Obj defeats the purpose.
One part of program can create object (and know _real_ object's class),
all other parts of program can use the created object (and know only
object's _base_ class), but some units of the others can use real
object's class again and are forced to cast base class reference to
derived class, and it can be done with dynamic_cast<>.

For instance, there is the design pattern named "decorator" . In order
to get special interface of "decorated" object we are forced to cast to
derived class.

Also there is the design pattern using "pointer to indefinite class"
(for store objects and reorder them in storage (sorting etc)). In order
to get true interface of "stored" object we are forced to cast to
derived class.

Dec 1 '06 #8

Grizlyk wrote:
Using typeid? Thats downright wrong, unsafe and complicated.

One can do like this:
void foo(Obj& obj)
{
Shape* sh=dynamic_cast <Shape*>(&obj );
if(sh){ /* Shape-specific code */ }

Color* co=dynamic_cast <Color*>(&obj );
if(co){ /* Color-specific code */ }
}
In my opinion most, if not all uses of dynamic_cast have bad design.
Namely they break LSP. The above is a perfect example.

but some units of the others can use real
object's class again and are forced to cast base class reference to
derived class, and it can be done with dynamic_cast<>.
They have no business accepting the base class interface then.
>
For instance, there is the design pattern named "decorator" . In order
to get special interface of "decorated" object we are forced to cast to
derived class.
Huh? Decorator is a way to extend functionality through *composition*.
It implements the interface of the decorated object and becomes a
mediator, performing extra functionality as needed.
>
Also there is the design pattern using "pointer to indefinite class"
(for store objects and reorder them in storage (sorting etc)). In order
to get true interface of "stored" object we are forced to cast to
derived class.
There is an any object container in boost. I don't see a whole lot of
use in that object per se. I have used the constructs it uses to do
its job in some stuff I worked on wrt units and dimensional
analysis....to allow an object of any unit type to exist (when units
are separate static types) and I didn't use any of the casting or type
identification stuff. Besides stuff like that I don't see how it has
much use in well designed software....I could be wrong but that's how I
see it.

Dec 1 '06 #9

shuisheng wrote:
Dear All,

Assume I have a class named Obj.

class Obj
{ };

And a class named Shape which is derived from Obj.

class Shape: public Obj
{ };

And a class named Color which is also derived form Obj.

class Color: public Obj
{ };

I have two objects.

Obj *pA = new Shape or Color;
Obj *pB = new Shape or Color;

How can I know if they have the same type?

I appreciate your help.
Techically you cant really know if two pointers are the same type, but
you can find if they have the interface you are looking for by dynamic
cast. If the cast succeeds then the type has the interface, if it fails
then the pointer will be empty:

#include <iostream>
#include <string>

struct base{
std::string name;
base(std::strin g const & name_in):name(n ame_in){}
virtual ~base(){} // some virtual function is required in the class
for dynamic cast to work
// a virtual destructor ensures that delete (if used) deletes the
actual object, not just the base
};

struct derived : base{
derived(std::st ring const & name):base(name ){}
};

struct derived_derived : derived{
derived_derived (std::string const & name):derived(n ame){}
};
// examine a base pointer to see what interfaces it has
void f( base* pb)
{
if (!pb){
std::cout << "empty pointer!\n";
return;
}
derived * pd = dynamic_cast<de rived*>(pb);
std::cout << pb->name << " is ";
if(!pd){
std::cout << "not ";
}
std::cout << "a derived\n";

derived_derived * pdd = dynamic_cast<de rived_derived*> (pb);
std::cout << pb->name << " is ";
if(!pdd){
std::cout << "not ";
}
std::cout << "a derived_derived \n\n";
}

int main()
{
base b("base");
derived d("derived");
derived_derived dd("derived_der ived");
base * pb = & b;
base * pd = & d;
base* pdd = & dd;

f(pb);
f(pd);
f(pdd);

}

/*
output:
base is not a derived
base is not a derived_derived

derived is a derived
derived is not a derived_derived

derived_derived is a derived
derived_derived is a derived_derived
*/

Dec 1 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1436
by: Esmeralda Weatherwax | last post by:
For 10 days now, a new online judge (a system for the verification of the correctness of submitted programs, which solve problems selected from a repository) has been available to the public. The Sphere Online Judge (SPOJ) is available at spoj.sphere.pl, and supports solutions written in 18 different programming languages including Haskell, Ocaml, Prolog, Icon and Ruby. At present, well over half the problems can be solved in...
0
1809
by: Esmeralda Weatherwax | last post by:
For 10 days now, a new online judge (a system for the verification of the correctness of submitted programs, which solve problems selected from a repository) has been available to the public. The Sphere Online Judge (SPOJ) is available at spoj.sphere.pl, and supports solutions written in different programming languages including Python.
49
2893
by: Steven Bethard | last post by:
I promised I'd put together a PEP for a 'generic object' data type for Python 2.5 that allows one to replace __getitem__ style access with dotted-attribute style access (without declaring another class). Any comments would be appreciated! Thanks! Steve ----------------------------------------------------------------------
58
4693
by: Jeff_Relf | last post by:
Hi Tom, You showed: << private const string PHONE_LIST = "495.1000__424.1111___(206)564-5555_1.800.325.3333"; static void Main( string args ) { foreach (string phoneNumber in Regex.Split (PHONE_LIST, "_+")) { Console.WriteLine (phoneNumber); } } Output: 495.1000
161
7877
by: KraftDiner | last post by:
I was under the assumption that everything in python was a refrence... so if I code this: lst = for i in lst: if i==2: i = 4 print lst I though the contents of lst would be modified.. (After reading that
6
2273
by: Morgan Cheng | last post by:
I know that HttpWebRequest.GetResponse() generates a HttpWebResonse. The response has one ContentType property. But the property is just decided by http response header. It is possible that the content is actually HTML, while the ContentType is "image/jpeg". Is there any effective way to judge whether the response type is truly "text"? I have a idea to read the first several bytes of the response stream; and check whether they are real...
26
1837
by: momobear | last post by:
hi, I am puzzled about how to determine whether an object is initilized in one class, anyone could give me any instructions? here is an example code: class coffee: def boil(self): self.temp = 80 a = coffer() if a.temp 60:
27
2568
by: SasQ | last post by:
Hello. I wonder if literal constants are objects, or they're only "naked" values not contained in any object? I have read that literal constants may not to be allocated by the compiler. If the Standard is saying that "object is a region of storage", I deduce from that that literal constants aren't objects because they may not be alocated as regions of storage in the memory.
19
10763
by: Daniel Pitts | last post by:
I have std::vector<Base *bases; I'd like to do something like: std::for_each(bases.begin(), bases.end(), operator delete); Is it possible without writing an adapter? Is there a better way? Is there an existing adapter? Thanks, Daniel.
0
9568
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10164
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10007
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9959
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9835
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8833
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5277
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3532
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.