C++/Class/cast — различия между версиями

Материал из C\C++ эксперт
Перейти к: навигация, поиск
м (1 версия: Импорт контента...)
 
(нет различий)

Версия 14:21, 25 мая 2010

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;
}