📄 chap22.lst
字号:
listing 1
// A simple example that uses typeid.
#include <iostream>
#include <typeinfo>
using namespace std;
class myclass1 {
// ...
};
class myclass2 {
// ...
};
int main()
{
int i, j;
float f;
char *p;
myclass1 ob1;
myclass2 ob2;
cout << "The type of i is: " << typeid(i).name();
cout << endl;
cout << "The type of f is: " << typeid(f).name();
cout << endl;
cout << "The type of p is: " << typeid(p).name();
cout << endl;
cout << "The type of ob1 is: " << typeid(ob1).name();
cout << endl;
cout << "The type of ob2 is: " << typeid(ob2).name();
cout << "\n\n";
if(typeid(i) == typeid(j))
cout << "The types of i and j are the same\n";
if(typeid(i) != typeid(f))
cout << "The types of i and f are not the same\n";
if(typeid(ob1) != typeid(ob2))
cout << "ob1 and ob2 are of differing types\n";
return 0;
}
listing 2
// An example that uses typeid on a polymorphic class heirarchy.
#include <iostream>
#include <typeinfo>
using namespace std;
class Mammal {
public:
virtual bool lays_eggs() { return false; } // Mammal is polymorphic
// ...
};
class Cat: public Mammal {
public:
// ...
};
class Platypus: public Mammal {
public:
bool lays_eggs() { return true; }
// ...
};
int main()
{
Mammal *p, AnyMammal;
Cat cat;
Platypus platypus;
p = &AnyMammal;
cout << "p is pointing to an object of type ";
cout << typeid(*p).name() << endl;
p = &cat;
cout << "p is pointing to an object of type ";
cout << typeid(*p).name() << endl;
p = &platypus;
cout << "p is pointing to an object of type ";
cout << typeid(*p).name() << endl;
return 0;
}
listing 3
// Use a reference with typeid.
#include <iostream>
#include <typeinfo>
using namespace std;
class Mammal {
public:
virtual bool lays_eggs() { return false; } // Mammal is polymorphic
// ...
};
class Cat: public Mammal {
public:
// ...
};
class Platypus: public Mammal {
public:
bool lays_eggs() { return true; }
// ...
};
// Demonstrate typeid with a reference parameter.
void WhatMammal(Mammal &ob)
{
cout << "ob is referencing an object of type ";
cout << typeid(ob).name() << endl;
}
int main()
{
Mammal AnyMammal;
Cat cat;
Platypus platypus;
WhatMammal(AnyMammal);
WhatMammal(cat);
WhatMammal(platypus);
return 0;
}
listing 4
cout << typeid(int).name();
listing 5
void WhatMammal(Mammal &ob)
{
cout << "ob is referencing an object of type ";
cout << typeid(ob).name() << endl;
if(typeid(ob) == typeid(Cat))
cout << "Cats don't like water.\n";
}
listing 6
// Demonstrating run-time type id.
#include <iostream>
using namespace std;
class Mammal {
public:
virtual bool lays_eggs() { return false; } // Mammal is polymorphic
// ...
};
class Cat: public Mammal {
public:
// ...
};
class Platypus: public Mammal {
public:
bool lays_eggs() { return true; }
// ...
};
class Dog: public Mammal {
public:
// ...
};
// A factory for objects derived from Mammal.
Mammal *factory()
{
switch(rand() % 3 ) {
case 0: return new Dog;
case 1: return new Cat;
case 2: return new Platypus;
}
return 0;
}
int main()
{
Mammal *ptr; // pointer to base class
int i;
int c=0, d=0, p=0;
// generate and count objects
for(i=0; i<10; i++) {
ptr = factory(); // generate an object
cout << "Object is " << typeid(*ptr).name();
cout << endl;
// count it
if(typeid(*ptr) == typeid(Dog)) d++;
if(typeid(*ptr) == typeid(Cat)) c++;
if(typeid(*ptr) == typeid(Platypus)) p++;
}
cout << endl;
cout << "Animals generated:\n";
cout << " Dogs: " << d << endl;
cout << " Cats: " << c << endl;
cout << " Platypuses: " << p << endl;
return 0;
}
listing 7
// Using typeid with templates.
#include <iostream>
using namespace std;
template <class T> class myclass {
T a;
public:
myclass(T i) { a = i; }
// ...
};
int main()
{
myclass<int> o1(10), o2(9);
myclass<double> o3(7.2);
cout << "Type of o1 is ";
cout << typeid(o1).name() << endl;
cout << "Type of o2 is ";
cout << typeid(o2).name() << endl;
cout << "Type of o3 is ";
cout << typeid(o3).name() << endl;
cout << endl;
if(typeid(o1) == typeid(o2))
cout << "o1 and o2 are the same type\n";
if(typeid(o1) == typeid(o3))
cout << "Error\n";
else
cout << "o1 and o3 are different types\n";
return 0;
}
listing 8
Base *bp, b_ob;
Derived *dp, d_ob;
bp = &d_ob; // base pointer points to Derived object
dp = dynamic_cast<Derived *> (bp); // cast to derived pointer OK
if(dp) cout << "Cast OK";
listing 9
bp = &b_ob; // base pointer points to Base object
dp = dynamic_cast<Derived *> (bp); // error
if(!dp) cout << "Cast Fails";
listing 10
// Demonstrate dynamic_cast.
#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;
}
listing 11
Base *bp;
Derived *dp;
// ...
if(typeid(*bp) == typeid(Derived)) dp = (Derived *) bp;
listing 12
dp = dynamic_cast<Derived *> (bp);
listing 13
// Use dynamic_cast to replace typeid.
#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;
// ************************************
// use typeid
// ************************************
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;
}
listing 14
// Demonstrate dynamic_cast on template classes.
#include <iostream>
using namespace std;
template <class T> class Num {
protected:
T val;
public:
Num(T x) { val = x; }
virtual T getval() { return val; }
// ...
};
template <class T> class SqrNum : public Num<T> {
public:
SqrNum(T x) : Num<T>(x) { }
T getval() { return val * val; }
};
int main()
{
Num<int> *bp, numInt_ob(2);
SqrNum<int> *dp, sqrInt_ob(3);
Num<double> numDouble_ob(3.3);
bp = dynamic_cast<Num<int> *> (&sqrInt_ob);
if(bp) {
cout << "Cast from SqrNum<int>* to Num<int>* OK.\n";
cout << "Value is " << bp->getval() << endl;
} else
cout << "Error\n";
cout << endl;
dp = dynamic_cast<SqrNum<int> *> (&numInt_ob);
if(dp)
cout << "Error\n";
else {
cout << "Cast from Num<int>* to SqrNum<int>* not OK.\n";
cout << "Can't cast a pointer to a base object into\n";
cout << "a pointer to a derived object.\n";
}
cout << endl;
bp = dynamic_cast<Num<int> *> (&numDouble_ob);
if(bp)
cout << "Error\n";
else
cout << "Can't cast from Num<double>* to Num<int>*.\n";
cout << "These are two different types.\n";
return 0;
}
listing 15
// Demonstrate const_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;
}
listing 16
// 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;
}
listing 17
// Use static_cast.
#include <iostream>
using namespace std;
int main()
{
int i;
for(i=0; i<10; i++)
cout << static_cast<double> (i) / 3 << " ";
return 0;
}
listing 18
// An example that uses reinterpret_cast.
#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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -