How would I do this dynamic_cast?

R

Rob

Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray jarray;

int main()
{
     jobject * a;
     jarray b;
     a = dynamic_cast<jobject*> (&b);
.....
}

This doesn't work and the problem is the only type names I'm
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.

How would I cast between jobject and jarray?
 
R

Rob

Sorry, I missed a "*" in there.

Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray* jarray;

int main()
{
     jobject * a;
     jarray b;
     a = dynamic_cast<jobject*> (&b);
.....
}
 
S

sk_usenet

Rob said:
Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray jarray;

int main()
{
jobject * a;
jarray b;
a = dynamic_cast<jobject*> (&b);
....
}

This doesn't work and the problem is the only type names I'm

Does this even compile?
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.

How would I cast between jobject and jarray?

I think you are not understanding what dynamic_cast does. You can always
assign a derived class pointer to a base class pointer with public
inheritance. The inverse may or may not hold true. This is where a run time
cast named dynamic_cast comes into picture. If the downcasting is
successful, then the address returned by dynamic_cast is non NULL.

Why do you require dynamic_cast? Can't virtual functions help you?
 
J

Jim Langston

Rob said:
Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray jarray;

int main()
{
jobject * a;
jarray b;
a = dynamic_cast<jobject*> (&b);
....
}

This doesn't work and the problem is the only type names I'm
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.

How would I cast between jobject and jarray?

jobject* a becomes _jobject** because jobject is _jobject*
jarray b becomes _jarray.

Now you're trying to cast &b which is address of _jarray which is _jarray*
to a jobject* which is _jobject***. You see the problem?
 
S

sk_usenet

Jim Langston said:
Rob wrote: [snip]
This doesn't work and the problem is the only type names I'm
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.

How would I cast between jobject and jarray?

jobject* a becomes _jobject** because jobject is _jobject*
jarray b becomes _jarray.

Now you're trying to cast &b which is address of _jarray which is _jarray*
to a jobject* which is _jobject***. You see the problem?

Even if he corrects that the intention to use dynamic_cast is not justified.
 
J

Jim Cobban

Rob said:
Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray jarray;

int main()
{
jobject * a;
jarray b;
a = dynamic_cast<jobject*> (&b);
....
}

This doesn't work and the problem is the only type names I'm
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.

How would I cast between jobject and jarray?

According to the declarations you have given jarray is a synonym for
_jarray which is derived from _jobject, but jobject is synonym for a
POINTER to a _jobject. &b returns a pointer to the instance of _jarray,
which can be converted without a cast, because it is just working up the
class hierarchy, to a pointer to _jobject, which is synonymous with
jobject, not with pointer to jobject. I do not know your objective, but
the following should compile:

int main()
{
jobject a;
jarray b;
a = &b;
}

dynamic_cast is used for moving DOWN the class hierarchy, not up. So if
you have a pointer to _jobject that you have reason to believe is
actually a pointer to _jarray you can:

_jobject * p;
_jarray * q;
// no cast required because an instance of _jarray
// is guaranteed to be an instance of _jobject
p = q;
if (Ihavereasontobelievethat_p_pointstoa_jarray) {
// dynamic_cast required so that the type of
// the _jobject can be verified at run time
q = dynamic_cast<_jarray *>(p);
}

As I see it the problem you are facing is that the name of the typedef
jobject is confusing because it does not warn the programmer that it is
a pointer to a class, not a class itself. If the architect had really
intended to use the jobject and jarray definitions to hide the internal
implementation then they should have been defined explicitly as classes,
not as typedefs.

In any event C++ pointers are extremely dangerous and should be avoided
as much as possible. They are a carryover artifact from C. Their use
exposes you to risks because the compiler cannot catch most misuses.
For example the compiler will permit you to use an instance of jobject
as an array! That is because C permits you to use any pointer as an
array. In your fragment of code what would happen if you coded:

a[3] = b; // !?
 
R

Rob

Rob said:
Code:
(I am not the one who defined these classes)[/QUOTE]
[QUOTE]
class _jobject {};
class _jarray : public _jobject {};[/QUOTE]
[QUOTE]
typedef _jobject* jobject;
typedef _jarray jarray;[/QUOTE]
[QUOTE]
int main()
{
     jobject * a;
     jarray b;
     a = dynamic_cast<jobject*> (&b);
....
}
This doesn't work and the problem is the only type names I'm
guaranteed to have are jobject and jarray. The original _jobject is
how it's defined here but I'm not guaranteed it''ll always be that way
so I have to work with jobject/jarray.
How would I cast between jobject and jarray?

According to the declarations you have given jarray is a synonym for
_jarray which is derived from _jobject, but jobject is synonym for a
POINTER to a _jobject.  &b returns a pointer to the instance of _jarray,
which can be converted without a cast, because it is just working up the
class hierarchy, to a pointer to _jobject, which is synonymous with
jobject, not with pointer to jobject.  I do not know your objective, but
the following should compile:

int main()
{
      jobject a;
      jarray b;
      a = &b;

}

dynamic_cast is used for moving DOWN the class hierarchy, not up.  So if
you have a pointer to _jobject that you have reason to believe is
actually a pointer to _jarray you can:

        _jobject *      p;
        _jarray *       q;
        // no cast required because an instance of _jarray
        // is guaranteed to be an instance of _jobject
        p       = q;
        if (Ihavereasontobelievethat_p_pointstoa_jarray) {
        // dynamic_cast required so that the type of
        // the _jobject can be verified at run time
        q       = dynamic_cast<_jarray *>(p);
        }

As I see it the problem you are facing is that the name of the typedef
jobject is confusing because it does not warn the programmer that it is
a pointer to a class, not a class itself.  If the architect had really
intended to use the jobject and jarray definitions to hide the internal
implementation then they should have been defined explicitly as classes,
not as typedefs.

In any event C++ pointers are extremely dangerous and should be avoided
as much as possible.  They are a carryover artifact from C.  Their use
exposes you to risks because the compiler cannot catch most misuses.
For example the compiler will permit you to use an instance of jobject
as an array!  That is because C permits you to use any pointer as an
array.  In your fragment of code what would happen if you coded:

        a[3]    = b;    // !?

Thanks!
 
N

Noah Roberts

Rob said:
Sorry, I missed a "*" in there.

Code:
(I am not the one who defined these classes)

class _jobject {};
class _jarray : public _jobject {};

typedef _jobject* jobject;
typedef _jarray* jarray;

int main()
{
jobject * a;
jarray b;
a = dynamic_cast<jobject*> (&b);
....
}[/QUOTE]

The reason this doesn't work is that such casts are simply not possible. 
  Once you start using multiple levels of dereference the type system 
fails.  You can't assign a _jarray** to a _jobject**...you just can't do 
it.

You could use a reinterpret_cast, but you're asking for a lot of trouble 
if you do.  By using reinterpret_cast you're saying to the compiler, "I 
know what I'm doing is insane and will inevitably cause me endless 
suffering, but I'm going to do it anyway so just shut the hell up and do 
the cast!"  All type information is then lost.

Whatever decisions guided you to attempt this are flawed.  Reevaluate 
your situation.

BTW, the names of your classes violate the standard.  Any name starting 
with '_' in the global namespace is reserved for the implementation to use.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top