C++/Class/cast
Содержание
- 1 class type-casting
- 2 Don"t need a cast to go up the inheritance hierarchy
- 3 Replacing typeid with dynamic_cast
- 4 The const_cast operator is used to explicitly override const and/or volatile in a cast.
- 5 The dynamic_cast performs a run-time cast that verifies the validity of a cast.
- 6 The reinterpret_cast operator converts one type into a fundamentally different type.
- 7 The static_cast operator performs a nonpolymorphic cast.
- 8 Use const_cast on a const reference.
class type-casting
#include <iostream>
using namespace std;
class CDummy {
float i,j;
};
class CAddition {
int x,y;
public:
CAddition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
CDummy d;
CAddition * padd;
padd = (CAddition*) &d;
cout << padd->result();
return 0;
}
Don"t need a cast to go up the inheritance hierarchy
class Base{
public:
Base() {};
virtual ~Base() {}
};
class Derived : public Base{
public:
Derived() {}
virtual ~Derived() {}
};
int main(int argc, char** argv)
{
Base* b;
Derived* d = new Derived();
b = d; // Don.t need a cast to go up the inheritance hierarchy
d = static_cast<Derived*>(b); // Need a cast to go down the hierarchy
Base base;
Derived derived;
Base& br = base;
Derived& dr = static_cast<Derived&>(br);
int i = 3;
double result = static_cast<double>(i) / 10;
return (0);
}
Replacing typeid with dynamic_cast
#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
public:
virtual void f() {}
};
class Derived : public Base {
public:
void derivedOnly() {
cout << "Is a Derived Object.\n";
}
};
int main()
{
Base *bp, b_ob;
Derived *dp, d_ob;
bp = &b_ob;
if(typeid(*bp) == typeid(Derived)) {
dp = (Derived *) bp;
dp->derivedOnly();
}
else
cout << "Cast from Base to Derived failed.\n";
bp = &d_ob;
if(typeid(*bp) == typeid(Derived)) {
dp = (Derived *) bp;
dp->derivedOnly();
}
else
cout << "Error, cast should work!\n";
// use dynamic_cast
bp = &b_ob;
dp = dynamic_cast<Derived *> (bp);
if(dp) dp->derivedOnly();
else
cout << "Cast from Base to Derived failed.\n";
bp = &d_ob;
dp = dynamic_cast<Derived *> (bp);
if(dp) dp->derivedOnly();
else
cout << "Error, cast should work!\n";
return 0;
}
The const_cast operator is used to explicitly override const and/or volatile in a cast.
#include <iostream>
using namespace std;
void sqrval(const int *val){
int *p;
// cast away const-ness.
p = const_cast<int *> (val);
*p = *val * *val; // now, modify object through v
}
int main(){
int x = 10;
cout << "x before call: " << x << endl;
sqrval(&x);
cout << "x after call: " << x << endl;
return 0;
}
The dynamic_cast performs a run-time cast that verifies the validity of a cast.
// The general form of dynamic_cast: dynamic_cast<target-type> (expr)
// the various situations that dynamic_cast can handle.
#include <iostream>
using namespace std;
class Base {
public:
virtual void f() { cout << "Inside Base\n"; }
};
class Derived : public Base {
public:
void f() { cout << "Inside Derived\n"; }
};
int main()
{
Base *bp, b_ob;
Derived *dp, d_ob;
dp = dynamic_cast<Derived *> (&d_ob);
if(dp) {
cout << "Cast from Derived * to Derived * OK.\n";
dp->f();
} else
cout << "Error\n";
cout << endl;
bp = dynamic_cast<Base *> (&d_ob);
if(bp) {
cout << "Cast from Derived * to Base * OK.\n";
bp->f();
} else
cout << "Error\n";
cout << endl;
bp = dynamic_cast<Base *> (&b_ob);
if(bp) {
cout << "Cast from Base * to Base * OK.\n";
bp->f();
} else
cout << "Error\n";
cout << endl;
dp = dynamic_cast<Derived *> (&b_ob);
if(dp)
cout << "Error\n";
else
cout << "Cast from Base * to Derived * not OK.\n";
cout << endl;
bp = &d_ob; // bp points to Derived object
dp = dynamic_cast<Derived *> (bp);
if(dp) {
cout << "Casting bp to a Derived * OK\n" <<
"because bp is really pointing\n" <<
"to a Derived object.\n";
dp->f();
} else
cout << "Error\n";
cout << endl;
bp = &b_ob; // bp points to Base object
dp = dynamic_cast<Derived *> (bp);
if(dp)
cout << "Error";
else {
cout << "Now casting bp to a Derived *\n" <<
"is not OK because bp is really \n" <<
"pointing to a Base object.\n";
}
cout << endl;
dp = &d_ob; // dp points to Derived object
bp = dynamic_cast<Base *> (dp);
if(bp) {
cout << "Casting dp to a Base * is OK.\n";
bp->f();
} else
cout << "Error\n";
return 0;
}
The reinterpret_cast operator converts one type into a fundamentally different type.
#include <iostream>
using namespace std;
int main()
{
int i;
char *p = "This is a string";
i = reinterpret_cast<int> (p); // cast pointer to integer
cout << i;
return 0;
}
The static_cast operator performs a nonpolymorphic cast.
#include <iostream>
using namespace std;
int main()
{
int i;
for(i=0; i<10; i++)
cout << static_cast<double> (i) / 3 << " ";
return 0;
}
Use const_cast on a const reference.
#include <iostream>
using namespace std;
void sqrval(const int &val)
{
// cast away const on val
const_cast<int &> (val) = val * val;
}
int main()
{
int x = 10;
cout << "x before call: " << x << endl;
sqrval(x);
cout << "x after call: " << x << endl;
return 0;
}