Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ For Dummies (2004) [eng].pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
8.09 Mб
Скачать

Chapter 22: Factoring Classes 289

isn’t necessarily true, but assume that it is.) To express the common write() property, introduce the class HWVGA to implement the write() function (along with any other properties that all HWVGA have in common). Don’t override the member function initialize(), however, because the different HWVGAs do not have this property in common.

Therefore, although the function write() has been overridden, the class HWVGA is still abstract because the initialize() function has yet to be overridden.

Because ThreedVGA inherits from HWVGA, it has to override only the one miss­ ing member function, initialize(), to complete the definition of Display adapter. The function fn() is therefore free to instance and use a ThreedVGA object.

Overriding the last pure virtual function with a normal member function makes the class complete (that is, non-abstract). Only non-abstract classes can be instanced with an object.

Passing abstract classes

Because you can’t instance an abstract class, it may sound odd that it’s possi­ ble to declare a pointer or a reference to an abstract class. With polymor­ phism, however, this isn’t as crazy as it sounds. Consider the following code snippet:

void fn(Account *pAccount); // this is legal void otherFn( )

{

Savings s; Checking c;

//this is legitimate because Savings IS_A Account fn(&s);

//same here

fn(&c);

}

Here, pAccount is declared as a pointer to an Account. However, it’s under­ stood that when the function is called, it will be passed the address of some non-abstract subclass object such as Savings or Checking.

All objects received by fn() will be of either class Savings or class Checking (or some future non-abstract subclass of Account). The function is assured that you will never pass an actual object of class Account because you could never create one to pass in the first place.

290 Part IV: Inheritance

Declaring pure virtual functions — is it really necessary?

If withdrawal() can’t be defined, why not leave it out? Why not declare the function in Savings and Checking where it can also be defined and keep it out of Account? In many object-oriented languages, you can do just that. But C++ wants to be able to check that you really know what you’re doing.

Remember that declaring a function establishes its extended name including arguments, whereas a definition includes the code to execute when the func­ tion is called.

I can make the following minor changes to Account to demonstrate the problem:

class Account

{

//just like before but without

//the declaration of withdrawal()

};

class Savings : public Account

{

public:

virtual void withdrawal(float amnt);

};

void fn(Account *pAcc)

{

// withdraw some money pAcc->withdrawal(100.00F);

//this call is not allowed

//withdrawal( ) is not a member

//of class Account

};

int main( )

{

Savings s; // open an account fn(&s);

// ...continues on...

}

Suppose that you open a savings account s. You then pass the address of that account to the function fn(), which attempts to make a withdrawal. Because the function withdrawal() is not a member of Account, however, the compiler generates an error.