C++/Function/Virtual
Содержание
- 1 A simple example using a virtual function.
- 2 Class pointer and virtual function
- 3 Use virtual function to define interface.
- 4 Virtual function and public inheritance
- 5 Virtual function and three level inheritance
- 6 Virtual function for two derived classes
- 7 Virtual function: respond to random events
- 8 Virtual functions are hierarchical.
- 9 Virtual functions retain virtual nature when inherited.
A simple example using a virtual function.
<source lang="cpp">
- 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;
}
</source>
Class pointer and virtual function
<source lang="cpp">
- 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;
}
</source>
Use virtual function to define interface.
<source lang="cpp">
- 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;
}
</source>
Virtual function and public inheritance
<source lang="cpp">
- 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;
}
</source>
Virtual function and three level inheritance
<source lang="cpp">
- 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;
}
</source>
Virtual function for two derived classes
<source lang="cpp">
- 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;
}
</source>
Virtual function: respond to random events
<source lang="cpp">
- 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;
}
</source>
Virtual functions are hierarchical.
<source lang="cpp">
- 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;
}
</source>
Virtual functions retain virtual nature when inherited.
<source lang="cpp">
- 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;
}
</source>