Online Book Reader

Home Category

Professional C__ - Marc Gregoire [109]

By Root 1446 0
Only methods that are declared as virtual in the superclass can be overridden properly by subclasses. The keyword goes at the beginning of a method declaration as shown in the modified version of Super that follows:

class Super

{

public:

Super();

virtual void someMethod();

protected:

int mProtectedInt;

private:

int mPrivateInt;

};

The virtual keyword has a few subtleties and is often cited as a poorly designed part of the language. A good rule of thumb is to just make all of your methods virtual. That way, you won’t have to worry about whether or not overriding the method will work. The only drawback is a very tiny performance hit. The subtleties of the virtual keyword are covered toward the end of this chapter, and performance is discussed further in Chapter 24.

Even though it is unlikely that the Sub class will be extended, it is a good idea to make its methods virtual as well, just in case.

class Sub : public Super

{

public:

Sub();

virtual void someOtherMethod();

};

As a rule of thumb, make all your methods virtual (including the destructor, but not constructors) to avoid problems associated with omission of the virtual keyword.

Syntax for Overriding a Method

To override a method, you redeclare it in the subclass class definition exactly as it was declared in the superclass. In the subclass’s implementation file, you provide the new definition.

For example, the Super class contains a method called someMethod(). The definition of someMethod() is provided in Super.cpp and shown here:

void Super::someMethod()

{

cout << "This is Super's version of someMethod()." << endl;

}

Note that you do not repeat the virtual keyword in front of the method definition.

If you wish to provide a new definition for someMethod() in the Sub class, you must first add it to the class definition for Sub, as follows:

class Sub : public Super

{

public:

Sub();

virtual void someMethod(); // Overrides Super's someMethod()

virtual void someOtherMethod();

};

The new definition of someMethod() is specified along with the rest of Sub’s methods in Sub.cpp.

void Sub::someMethod()

{

cout << "This is Sub's version of someMethod()." << endl;

}

Once a method or destructor is marked as virtual, it will be virtual for all subclasses even if the virtual keyword is removed from subclasses. For example, in the following Sub class, someMethod() is still virtual and can still be overridden by subclasses of Sub, because it was marked as virtual in the Super class.

class Sub : public Super

{

public:

Sub();

void someMethod(); // Overrides Super's someMethod()

};

A Client’s View of Overridden Methods

With the preceding changes, other code would still call someMethod() the same way it did before. Just as before, the method could be called on an object of class Super or an object of class Sub. Now, however, the behavior of someMethod() will vary based on the class of the object.

For example, the following code works just as it did before, calling Super’s version of someMethod():

Super mySuper;

mySuper.someMethod(); // Calls Super's version of someMethod().

The output of this code is:

This is Super's version of someMethod().

If the code declares an object of class Sub, the other version will automatically be called:

Sub mySub;

mySub.someMethod(); // Calls Sub's version of someMethod()

The output this time is:

This is Sub's version of someMethod().

Everything else about objects of class Sub remains the same. Other methods that might have been inherited from Super will still have the definition provided by Super unless they are explicitly overridden in Sub.

As you learned earlier, a pointer or reference can refer to an object of a class or any of its subclasses. The object itself “knows” the class of which it is actually a member, so the appropriate method is called as long as it was declared virtual. For example, if you have a Super reference that refers to an object that is really a Sub, calling someMethod() will actually call the subclass’s version, as shown next. This aspect of overriding will not work properly

Return Main Page Previous Page Next Page

®Online Book Reader