Would a static_cast be better style here?

Would a static_cast be better style here?

Post by Steven T. » Sat, 17 Apr 2004 22:01:01


The code shown below is an example from the Coin3D documentation. I believe
the use of the C-style cast is safe under the circumstances, but from what
I've been exposed to (TC++PL(SE)), I would favor using a static_cast. Is
there any technical reason to favor the C-style over a static_cast?

http://www.yqcomputer.com/

void foo(SoNode * node)
{
if (node->getTypeId() == SoFile::getClassTypeId()) {
SoFile * filenode = (SoFile *)node; // safe downward cast, knows the
type
}
else if (node->getTypeId().isOfType(SoGroup::getClassTypeId())) {
SoGroup * group = (SoGroup *)node; // safe downward cast, knows the
type
}
}

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.yqcomputer.com/ SuSE: http://www.yqcomputer.com/
Mozilla: http://www.yqcomputer.com/
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sat, 17 Apr 2004 22:14:17


believe


No, if you need a cast, use only the new C++ ones (static_cast,
dynamic_cast, reinterprer_cast). They are there for a reason, to help you
identify potential problems. For example if your code crashes, the first
thing you will do is check the reinterpret_casts at first.






Ioannis Vranos

 
 
 

Would a static_cast be better style here?

Post by Nils Pette » Sat, 17 Apr 2004 22:21:25


One advantage beeing that you can much more easily search for
static_cast<something>(variable) than (something) variable.

--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up
 
 
 

Would a static_cast be better style here?

Post by Peter Koch » Sat, 17 Apr 2004 23:30:33


"Steven T. Hatton" < XXXX@XXXXX.COM > skrev i en meddelelse

believe

None whatsoever. Actually, I would advice you never ever use the C-style
cast. The only purpose of it is to be compatible with C.

/Peter
 
 
 

Would a static_cast be better style here?

Post by jcoffi » Sun, 18 Apr 2004 08:30:03


Given the situation, you _probably_ want to use a dynamic_cast instead
of either one. Generally this is a type of situation you want to
avoid though -- except in a few situations like re-creating an object
that's been persisted to a stream of some sort, downcasting tends to
indicate poor design.

Downcasting gives you direct access to the functionality of a derived
class. Generally speaking, the preferred method of doing this is to
wrap that functionality in a virtual functio in the base class so you
can use it without casting down to the derived type.

Contrary to statements elsethread, a C-style cast can do one thing
none of the new casts can. It has nothing to do with the question at
hand, so I won't go into it, but it does exist.
Later,
Jerry.

The universe is a figment of its own imagination.
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 09:27:54


believe
what
Is


For downcasts static_cast is better to be used. dynami_cast is for upcasting
and crosscasting.






Don't tease our curiosity. Tell it. :-)






Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Kevin Good » Sun, 18 Apr 2004 10:47:40


"Upcasting" is never necessary, as far as I can tell. dynamic_cast is
used for checked downcasting (e.g., if I cast from Shape to Triangle,
ensures that the Shape really was a Triangle).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 10:49:58


Yes my silly mistake. Downcasting and crosscasting is dynamic_cast about.
Upcasting needs no casting.







Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Steven T. » Sun, 18 Apr 2004 16:13:01


OK, which way is up? Actually, I didn't even think about that issue. But now
that I think about it. A dynamic_cast would be the thing to use. Upcasting
actually means to cast from a derived to a base class, and _does_, I'm
pretty sure, require a static_cast.

This is a little exercise I made up to try to get a handle on all this.
It's a very tricky topic.
/* Hava Fun */
#include <iostream>
#include <string>
using std::ostream;
using std::string;
using std::cout;

class A{
public:
A(const string& name = "A"):m_name(name)
{}
virtual ostream& toString (ostream& out) const;
friend ostream& operator<<(ostream& out, const A& a);
protected:
string m_name;
};

ostream& A::toString (ostream& out) const{
return out << this->m_name;
}

ostream& operator<<(ostream& out, const A& a)
{
return a.toString(out);
}


class B:public A
{
public:
B(const string& name = "B"):A(name)
{}
ostream& toString (ostream& out) const;

};

ostream& B::toString (ostream& out) const{
A::toString(out);
return out << this->m_name;
}

ostream& operator<<(ostream& out, const B& b)
{
return b.toString(out);
}

int main()
{

A a;
B b;
A* aa_ptr = &a;
A* ab_ptr = &b;
B* bb_ptr = &b;
cout << "A* aa_ptr = &a: " << *aa_ptr << std::endl;
cout << "A* ab_ptr = &b: " << *ab_ptr << std::endl;
cout << "B* bb_ptr = &b: " << *bb_ptr << std::endl;

ab_ptr = static_cast<A*>(&b);
cout<<"ab_ptr = static_cast<A*>(&b): " << *ab_ptr << std::endl;

ab_ptr = dynamic_cast<A*>(&b);

cout << "ab_ptr = dynamic_cast<A*>(&b): " << *ab_ptr << std::endl;

cout << "cout <<(A)*ab_ptr << std::endl;: " <<(A)*ab_ptr << std::endl;

cout << "cout << static_cast<A>(*ab_ptr) << std::endl;: ";
cout <<static_cast<A>(*ab_ptr) << std::endl;

cout << "cout << *dynamic_cast<A*>(ab_ptr) << std::endl;: ";
cout << *dynamic_cast<A*>(ab_ptr) << std::endl;
}

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.yqcomputer.com/ SuSE: http://www.yqcomputer.com/
Mozilla: http://www.yqcomputer.com/
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 22:38:39


now
Upcasting


No it doesn't, else inheritance would not work properly:


class base
{
// ...
public:
virtual void something() { // .. }
};


class derived1: public base
{
// ...
};

class derived2: public base
{
// ...
};



void some_func(const base *p)
{
p->something();
}

int main()
{
derived 1 d;

some_func(&d);
}





To get handle of what.





I haven't drunk my coffee yet. May be later.







Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 23:37:40


I took a look at TC++PL to refresh my memory and in summary dynamic_cast is
usually used for downcasts and crosscasts but the type of the object must be
polymorphic, that is to have virtual functions.

static_cast converts between related types, such as one pointer to another
in the same class hierarchy.

reinterpret_cast handles conversions between unrelated types.

dynamic_cast is a form of run-time checked conversion, and is usually used
for downcasts and crosscasts and the type of the object must be
*polymorphic*, that is to have virtual functions.


So if in an hierarchy and you want to perform (compile-time checked)
related- type conversion use static_cast. If you want to check at runtime if
the types are related use dynamic_cast provided that the object is
polymorphic if you want the cast to not indicate failure although it is
correct.


Examples:

#include <iostream>

class A
{
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=dynamic_cast<B *>(p);

std::cout<<bp<<std::endl;
}


"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp

temp.cpp: In function `int main()':
temp.cpp:18: error: cannot dynamic_cast `p' (of type `class A*') to type
`class
B*' (source type is not polymorphic)



#include <iostream>

class A
{
public:
virtual void something() const {}
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=dynamic_cast<B *>(p);

std::cout<<bp<<std::endl;
}



"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp






#include <iostream>

class A
{
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=static_cast<B *>(p);

std::cout<<bp<<std::endl;
}



"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp







Ioannis Vranos



Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 23:44:58


The same put into shape:

I took a look at TC++PL to refresh my memory and in summary,


static_cast converts between related types, such as one pointer to another
in the same class hierarchy. The conversion is compile-time checked.

reinterpret_cast handles conversions between unrelated types.

dynamic_cast is a form of run-time checked conversion, and the type of the
object must be *polymorphic*, that is to have virtual functions.


So if in an hierarchy and you want to perform (compile-time checked) related
type conversion use static_cast.

If you want to check at runtime if the types are related use dynamic_cast
provided that the object is polymorphic.

If you want to convert between oranges and potatoes use reinterpret_cast.



Examples:

#include <iostream>

class A
{
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=dynamic_cast<B *>(p);

std::cout<<bp<<std::endl;
}


"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp

temp.cpp: In function `int main()':
temp.cpp:18: error: cannot dynamic_cast `p' (of type `class A*') to type
`class
B*' (source type is not polymorphic)



#include <iostream>

class A
{
public:
virtual void something() const {}
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=dynamic_cast<B *>(p);

std::cout<<bp<<std::endl;
}



"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp






#include <iostream>

class A
{
};

class B: public A
{
};

int main()
{
B b;

A *p=&b;


B *bp=static_cast<B *>(p);

std::cout<<bp<<std::endl;
}



"C:\MinGW\bin\g++.exe" -std=c++98 -pedantic-errors -O3 -Wall "temp.cpp" -o
temp







Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Ioannis Vr » Sun, 18 Apr 2004 23:47:36


related



And of course to convert from a derived pointer type to a base pointer type
there is no need to cast.






Ioannis Vranos
 
 
 

Would a static_cast be better style here?

Post by Steven T. » Mon, 19 Apr 2004 03:23:12


I believe it depends on what the objective is. If you want to call methods
on the base class instead of on the derived class, I'm pretty sure you need
a static cast to the *object* (not the pointer) when you invoke the
function. If you just want to point to a derived object with a base class
pointer, then you are correct, there is no need to cast.

I haven't tried it yet, but I believe you may also be able to used a scope
resolution operator to directly invoke a baseclass function.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.yqcomputer.com/ SuSE: http://www.yqcomputer.com/
Mozilla: http://www.yqcomputer.com/
 
 
 

Would a static_cast be better style here?

Post by alfp » Mon, 19 Apr 2004 04:38:07

* "Steven T. Hatton" < XXXX@XXXXX.COM > schriebt:


For a virtual function the scope resolution operator is the only way.

A cast won't make any difference for a virtual function.

Btw., the notion that a cast will make a difference for a virtual function is
very common, especially among Java programmers (it doesn't make a difference
in Java either), so you're absolutely not the first one to think so. ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?