C++/Function/Virtual

Материал из C\C++ эксперт
Перейти к: навигация, поиск

A simple example using a virtual function.

#include <iostream>
using namespace std;
class BaseClass {
public:
  int i;
  BaseClass(int x) { 
     i = x; 
  }
  virtual void myFunction()
  {
    cout << "Using BaseClass version of myFunction(): ";
    cout << i << "\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  DerivedClass1(int x) : BaseClass(x) {}
  void myFunction() 
  {
    cout << "Using DerivedClass1"s version of myFunction(): ";
    cout << i*i << "\n";
  }
};
class DerivedClass2 : public BaseClass {
public:
  DerivedClass2(int x) : BaseClass(x) {}
  void myFunction() 
  {
    cout << "Using DerivedClass2"s version of myFunction(): ";
    cout << i+i << "\n";
  }
};
int main()
{
  BaseClass *p;
  BaseClass ob(10);  
  DerivedClass1 derivedObject1(10);   
  DerivedClass2 derivedObject2(10); 
  p = &ob;
  p->myFunction();                         // use BaseClass"s myFunction()
  p = &derivedObject1;
  p->myFunction();                         // use DerivedClass1"s myFunction()
  p = &derivedObject2;
  p->myFunction();                         // use DerivedClass2"s myFunction()
  return 0;
}


Class pointer and virtual function

#include <iostream>
using namespace std;
class figure {
protected:
  double x, y;
public:
  void set_dim(double i, double j=0) {
    x = i;
    y = j;
  }
  virtual void show_area() {
    cout << "No area computation defined ";
    cout << "for this class.\n";
  }
} ;
class triangle : public figure {
  public:
    void show_area() {
      cout << "Triangle with height ";
      cout << x << " and base " << y;
      cout << " has an area of ";
      cout << x * 0.5 * y << ".\n";
    }
};
class rectangle : public figure {
  public:
    void show_area() {
      cout << "Rectangle with dimensions ";
      cout << x << "x" << y;
      cout << " has an area of ";
      cout << x *  y << ".\n";
    }
};
class circle : public figure {
  public:
    void show_area() {
      cout << "Circle with radius ";
      cout << x;
      cout << " has an area of ";
      cout << 3.14 * x * x << ".\n";
    }
} ;
  
int main()
{
  figure *p;  // create a pointer to base type
  triangle t; // create objects of derived types
  rectangle s;
  circle c;
  p = &t;
  p->set_dim(10.0, 5.0);
  p->show_area();
  p = &s;
  p->set_dim(10.0, 5.0);
  p->show_area();  
  p = &c;
  p->set_dim(9.0);
  p->show_area(); 
  return 0;
}


Use virtual function to define interface.

#include <iostream>
using namespace std;
class area {
  double dim1, dim2; 
public:
  void setarea(double d1, double d2)
  {
    dim1 = d1;
    dim2 = d2;
  }
  void getdim(double &d1, double &d2)
  {
    d1 = dim1;
    d2 = dim2;
  }
  virtual double getarea()
  { 
    cout << "You must override this function\n";
    return 0.0;
  }
};
class rectangle : public area {
public:
  double getarea() 
  {
    double d1, d2;
    getdim(d1, d2);
    return d1 * d2;
  }
};
class triangle : public area {
public:
  double getarea()
  {
    double d1, d2;
  
    getdim(d1, d2);
    return 0.5 * d1 * d2;
  }
};
int main()
{
  area *p;
  rectangle r;
  triangle t;
  r.setarea(3.3, 4.5);
  t.setarea(4.0, 5.0);
  p = &r;
  cout << "Rectangle has area: " << p->getarea() << "\n";
  p = &t;
  cout << "Triangle has area: " << p->getarea() << "\n";
  return 0;
}


Virtual function and public inheritance

#include <iostream>
using namespace std;
class BaseClass {
public:
  virtual void virtualFunction() {
    cout << "Base\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  void virtualFunction() {
    cout << "First derivation\n";
  }
};
class DerivedClass2 : public BaseClass {
};
int main()
{
  BaseClass baseObject;
  BaseClass *p;
  DerivedClass1 derivedObject1;
  DerivedClass2 derivedObject2;
  p = &baseObject;
  p->virtualFunction();  // access BaseClass"s virtualFunction()
  p = &derivedObject1;
  p->virtualFunction(); // access DerivedClass1"s virtualFunction()
  p = &derivedObject2;
  p->virtualFunction(); 
  return 0;
}


Virtual function and three level inheritance

#include <iostream>
using namespace std;
class BaseClass {
public:
  virtual void virtualFunction() {
    cout << "Base\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  void virtualFunction() {
    cout << "First derivation\n";
  }
};
class DerivedClass2 : public DerivedClass1 {
};
int main()
{
  BaseClass baseObject;
  BaseClass *p;
  DerivedClass1 derivedObject1;
  DerivedClass2 derivedObject2;
  p = &baseObject;
  p->virtualFunction();
  p = &derivedObject1;
  p->virtualFunction();
  p = &derivedObject2;
  p->virtualFunction();
  return 0;
}


Virtual function for two derived classes

#include <iostream>
using namespace std;
class figure {
protected:
  double x, y;
public:
  void set_dim(double i, double j) {
    x = i;
    y = j;
  }
  virtual void show_area() {
    cout << "No area computation defined ";
    cout << "for this class.\n";
  }
} ;
class triangle : public figure {
  public:
    void show_area() {
      cout << "Triangle with height ";
      cout << x << " and base " << y;
      cout << " has an area of ";
      cout << x * 0.5 * y << ".\n";
    }
};
class rectangle : public figure {
  public:
    void show_area() {
      cout << "Rectangle with dimensions ";
      cout << x << "x" << y;
      cout << " has an area of ";
      cout << x *  y << ".\n";
    }
};
int main()
{
  figure *p; // create a pointer to base type
  triangle t; // create objects of derived types
  rectangle s;
  p = &t;
  p->set_dim(10.0, 5.0);
  p->show_area();
  p = &s;
  p->set_dim(10.0, 5.0);
  p->show_area();  
  
  return 0;
}


Virtual function: respond to random events

#include <iostream>
#include <cstdlib>
using namespace std;
class BaseClass {
public:
  int i;
  BaseClass(int x) { 
     i = x; 
  }
  virtual void myFunction()
  {
    cout << "Using BaseClass version of myFunction(): ";
    cout << i << "\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  DerivedClass1(int x) : BaseClass(x) {}
  void myFunction() 
  {
    cout << "Using DerivedClass1"s version of myFunction(): ";
    cout << i*i << "\n";
  }
};
class DerivedClass2 : public BaseClass {
public:
  DerivedClass2(int x) : BaseClass(x) {}
  void myFunction() 
  {
    cout << "Using DerivedClass2"s version of myFunction(): ";
    cout << i+i << "\n";
  }
};
int main()
{
  BaseClass *p;
  DerivedClass1 derivedObject1(10);   
  DerivedClass2 derivedObject2(10); 
  int i, j;
  for(i = 0; i <10; i++) {
    j = rand();
    if( ( j % 2 ) ) 
       p = &derivedObject1; 
    else 
       p = &derivedObject2; 
    p->myFunction();                      // call appropriate function
  }
  return 0;
}


Virtual functions are hierarchical.

#include <iostream>
using namespace std;
class BaseClass {
public:
  int i;
  BaseClass(int x) { 
     i = x; 
  }
  virtual void myFunction()
  {
    cout << "Using BaseClass version of myFunction(): ";
    cout << i << "\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  DerivedClass1(int x) : BaseClass(x) {}
  void myFunction() 
  {
    cout << "Using DerivedClass1"s version of myFunction(): ";
    cout << i*i << "\n";
  }
};
class DerivedClass2 : public BaseClass {
public:
  DerivedClass2(int x) : BaseClass(x) {}
};
int main()
{
  BaseClass *p;
  BaseClass ob(10);  
  DerivedClass1 derivedObject1(10);   
  DerivedClass2 derivedObject2(10); 
  p = &ob;
  p->myFunction();                       // use BaseClass"s myFunction()
  p = &derivedObject1;
  p->myFunction();                       // use DerivedClass1"s myFunction()
  p = &derivedObject2;
  p->myFunction();                       // use BaseClass"s myFunction()
  return 0;
}


Virtual functions retain virtual nature when inherited.

#include <iostream>
using namespace std;
class BaseClass {
public:
  virtual void myFunction()
  {
    cout << "Using BaseClass version of myFunction()\n";
  }
};
class DerivedClass1 : public BaseClass {
public:
  void myFunction() 
  {
    cout << "Using DerivedClass1"s version of myFunction()\n";
  }
};
class DerivedClass2 : public DerivedClass1 {
public:
  void myFunction() 
  {
    cout << "Using DerivedClass2"s version of myFunction()\n";
  }
};
int main()
{
  BaseClass *p;
  BaseClass ob;
  DerivedClass1 derivedObject1;
  DerivedClass2 derivedObject2;
  p = &ob;
  p->myFunction();                   // use BaseClass"s myFunction()
  p = &derivedObject1;
  p->myFunction();                   // use DerivedClass1"s myFunction()
  p = &derivedObject2;
  p->myFunction();                   // use DerivedClass2"s myFunction()
  return 0;
}