Handout 25

Qualifiers, Abstract Classes and Virtual Functions*


Qualifiers That Appear Before a Class Member:

Private - When preceding a list of class members, the private keyword specifies that those members are accessible only from member functions and friends of the class.

Protected - When preceding a list of class members, the protected keyword specifies that those members are accessible only from member functions and friends of the class and its derived classes.

Public - When preceding a list of class members, the public keyword specifies that those members are accessible from any function.

Inheritance - Qualifiers Proceeding a Base Class

Private - When preceding the name of a base class, the private keyword specifies that the public and protected members of the base class are private members of the derived class.

Protected - When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of the derived class.

Public - When preceding the name of a base class, the public keyword specifies that the public and protected members of the base class are public and protected members, respectively, of the derived class.


The Deitel/Deitel Table

In Deitel/Deitel, a table is provided that specifies accessibility in derived classes.

Base class member access specifier

Public Inheritance

Protected Inheritance

Private Inheritance

Public public in derived class.

Can be accessed directly by any non-static member functions, friend functions and non-member functions.
protected in derived class.

Can be accessed directly by all non-static member functions and friend functions.
private in derived class.

Can be accessed directly by all non-static member functions and f riend functions.
Protected protected in derived class.

Can be accessed directly by all non-static member functions and friend functions.
protected in derived class.

Can be accessed directly by all non-static member functions and friend functions.
private in derived class.

Can be accessed directly by all non-static member functions and friend functions.
Private Hidden in derived class.

Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class.
Hidden in derived class.

Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class.
Hidden in derived class.

Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class.


Virtual

The virtual keyword declares a virtual function or a virtual base class.

Virtual Function

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

The virtual keyword is needed only in the base class's declaration of the function; any subsequent declarations in derived classes are virtual by default.

A derived class's version of a virtual function must have the same parameter list and return type as those of the base class. If these are different, the function is not considered a redefinition of the virtual function. A redefined virtual function cannot differ from the original only by return type.

Abstract Class (via pure virtual function)

An abstract class contains at least one pure virtual function. Specify a virtual function as pure by placing = 0 at the end of its declaration. You don't have to supply a definition for a pure virtual function.

You cannot declare an instance of an abstract base class; you can use it only as a base class when declaring other classes.

Virtual Function Example (source code)**

1    #include <iostream.h>
2    #include <string.h>
3
4    const int NAME_SIZE = 30;
5    const float PI = 3.14159;
6
7    class Shape {
8       public:
9          Shape() { }
10         ~Shape() { }
11         virtual float area() const = 0;  // pure virtual (makes Shape abstract)
12         virtual char * give_name() { return name; }  // virtual
13      protected:
14         char name[NAME_SIZE];
15   };
16
17   class Point : public Shape {
18      public:
19         Point() { strcpy(name, "Point"); }
20         ~Point() { }
21         float area() const { return 0.0;}
22         char * give_name() { return name; }
23   };
24
25   class Circle : public Shape {
26      public:
27         Circle() { strcpy(name, "Circle"); radius = 0.0; }
28         Circle(float x) { strcpy(name, "Circle"); radius = x; }
29         ~Circle() { }
30         float area() const { return (float) radius * radius * PI;}
31         char * give_name() { return name; }
32
33      private:
34         float radius;
35   };
36
37   class Square : public Shape {
38      public:
39         Square() { strcpy(name, "Square"); side = 0.0; }
40         Square(float x) { strcpy(name, "Square"); side = x; }
41         ~Square() { }
42         float area() const { return side * side;}
43         char * give_name() { return name; }
44
45      private:
46         float side;
47   };
48
49   int main() {
50     Shape * shape_ptr[3];
51     Point apoint;
52     Circle a_circle(1.0);
53     Square a_square(2.0);
54
55     shape_ptr[0] = &apoint;
56
57     cout << "atrributes are " <<  (shape_ptr[0] -> give_name()) << " area = " <<
58             (shape_ptr[0] -> area()) << endl;
59     cout << "atrributes are " <<  (apoint.give_name()) << " area = " <<
60             (apoint.area()) << endl;
61
62
63     shape_ptr[1] = &a_square;
64
65     cout << "atrributes are " <<  (shape_ptr[1] -> give_name()) << " area = " <<
66             (shape_ptr[1] -> area()) << endl;
67     cout << "atrributes are " <<  (a_square.give_name()) << " area = " <<
68             (a_square.area()) << endl;
69
70
71     shape_ptr[2] = &a_circle;
72
73     cout << "atrributes are " <<  (shape_ptr[2] -> give_name()) << " area = " <<
74          (shape_ptr[2] -> area()) << endl;
75     cout << "atrributes are " <<  (a_circle.give_name()) << " area = " <<
76          (a_circle.area()) << endl;
77
78     return 0;
79   }
/* output
atrributes are Point area = 0
atrributes are Point area = 0
atrributes are Square area = 4
atrributes are Square area = 4
atrributes are Circle area = 3.14159
atrributes are Circle area = 3.14159
*/


*definitions from Visual C++ on-line help, ** array of pointers approach suggested by A. Wedman.