C++/Class/cast — различия между версиями
Admin (обсуждение | вклад) м (1 версия: Импорт контента...) |
|
(нет различий)
|
Версия 17:21, 25 мая 2010
Содержание
- 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
<source lang="cpp">
- 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;
}
</source>
Don"t need a cast to go up the inheritance hierarchy
<source lang="cpp"> 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);
}
</source>
Replacing typeid with dynamic_cast
<source lang="cpp">
- 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;
}
</source>
The const_cast operator is used to explicitly override const and/or volatile in a cast.
<source lang="cpp">
- 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;
}
</source>
The dynamic_cast performs a run-time cast that verifies the validity of a cast.
<source lang="cpp"> // 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;
}
</source>
The reinterpret_cast operator converts one type into a fundamentally different type.
<source lang="cpp">
- 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;
}
</source>
The static_cast operator performs a nonpolymorphic cast.
<source lang="cpp">
- include <iostream>
using namespace std;
int main() {
int i; for(i=0; i<10; i++) cout << static_cast<double> (i) / 3 << " "; return 0;
}
</source>
Use const_cast on a const reference.
<source lang="cpp">
- 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;
}
</source>