䊐 Assignments Implicit type conversion in class hierarchies occurs in assignments to ■ base class objects ■ pointers or references to the base class.. Given the function comparewith the
Trang 15 2 9
Type Conversion in Class Hierarchies
This chapter describes implicit type conversion within class hierarchies, which occurs in the context of assignments and function calls
In addition, explicit type casting in class hierarchies is discussed, in particular, upcasting and downcasting
Trang 2530 C H A P T E R 2 4 T Y P E C O N V E R S I O N I N C L A S S H I E R A R C H I E S
Example for implicit conversion
#include "car.h"
bool compare( Car&, Car&);
int main() {
PassCar beetle("New Beetle", false, 3421, "VW"), miata( "Miata", true, 2512, "Mazda"); bool res = compare( beetle, miata);
//
} // ok!
// Implicit conversion // to base class
// Car& a = beetle; // Car& b = miata; bool compare( Car& a, Car& b)
{ // Here a is the base part of beetle, // b is the base part of miata
// If this is inconvenient, an explicit // type cast to type PassCar has to be performed }
Trang 3䊐 Implicit Conversion
If a class is derived from another class by publicinheritance, the derived class assumes the characteristics and features of the base class Objects of the derived class type then
become special objects of the base class, just like an automobile is a special type of
vehi-cle
You can utilize the is relationship when handling objects It is possible to assign an object of a derived class to an object of the base class This causes an implicit type conver-sion to a base class type.
The base class thus becomes a generic term for multiple special cases Given that the classesPassCarandTruckwere derived from the Carclass, objects of the PassCar
orTrucktype can always be managed like objects of Cartype
䊐 Assignments
Implicit type conversion in class hierarchies occurs in assignments to
■ base class objects
■ pointers or references to the base class
䊐 Function Calls
Additionally, a similar kind of implicit type conversion takes place for the arguments of function calls
Given the function compare()with the following prototype
Example: bool compare( Car& , Car& );
and two objects of the derived PassCarclass type, beetle andmiata, the following statement is valid
Example: compare( beetle, miata);
The compiler performs implicit type conversion for the arguments beetleandmiata, converting them to the parameter type, that is, to a reference to the base class Car Type conversion for arguments used in function calls is similar to the type conversion that occurs in assignments, as shown in the following section
Trang 4532 C H A P T E R 2 4 T Y P E C O N V E R S I O N I N C L A S S H I E R A R C H I E S
nr: 4325 producer:
"Bayer "
nr: 4325
sunRoof: true
producer:
"Bayer "
passCarType:
"520i"
䊐 Effect of an assignment
Car auto;
PassCar bmw("520i", true, 4325,
"Bayerische Motorenwerke");
auto = bmw;
Trang 5䊐 Assignment to a Base Class Object
An object belonging to a derived class type can be assigned to an object of a base class
Example: Car auto;
PassCar bmw("520i", true, 4325,
"Bayerische Motorenwerke");
auto = bmw;
The object bmw, which belongs to the derived class PassCar, contains all the data members of the base class, Car, i.e the vehicle id number and the manufacturer During
an assignment the object bmwis copied to the data members of the object autostep by step
This makes the above statement equivalent to:
auto.nr = bmw.nr;
auto.producer = bmw.producer;
The data members additionally defined in the derived class are not copied!
The following statement outputs the copied data members:
Example: auto.display();
The fact that you can assign an object belonging to a derived class to a base class object assumes that more will always fill less The object on the right of the assignment operator will always contain a member object of the type on the left of the operator
䊐 Assignments to Derived Class Objects
This is not the case when you attempt to assign a base class object to an object of a derived class The assignment
Example: bmw = auto; // Error!
is therefore invalid, since the values for the additional data members passCarTypeand sunRoofare unknown
An assignment in reverse order is only possible if you have defined an assignment of this type or a copy constructor with a parameter of the type “reference to base class.” Both would be able to supply default values for the additional data members of the derived classes
Trang 6534 C H A P T E R 2 4 T Y P E C O N V E R S I O N I N C L A S S H I E R A R C H I E S
carPtr cabrio
nr producer
1001
"Triumph"
䊐 Effect of a pointer assignment
PassCar cabrio("Spitfire", true, 1001, "Triumph"); Car* carPtr = &cabrio;
carPtr = &cabrio;
Trang 7䊐 Converting to Base Class Pointers
The is relationship between a derived class and a base class is also apparent when refer-ences and pointers are used A pointer of the type “pointer to base class,” or base class pointer for short, can reference an object of a derived class type.
Example: Car* carPtr = &cabrio;
In this case cabriois an object of the class PassCar
The following rule applies for access to the referenced object:
■ a base class pointer can only access the public interface of the base class
The additional members defined in the derived class are therefore inaccessible To make this more clear:
Example: carPtr -> display();
calls the display() method in the base class Car Although carPtr points to an object of the PassCarclass in this case, it is impossible to call any methods additionally defined in the derived class
Example: carPtr->setSunRoof(false); // Error
The object *carPtrbelongs to the Carclass and only represents the generic part of cabrio Thus, the following assignment is also invalid
Example: PassCar auto;
auto = *carPtr; // Error!
althoughcarPtris pointing at an object of the PassCartype in this case!
䊐 Conversions in References to Base Classes
A similar situation arises when you are working with references A reference of the type
“reference to base class” can point to an object of a derived class The reference will address only the generic part of the object in this case
Example: Car& carRef = cabrio; // ok
carRef.display(); // Output base members carRef.setSunRoof(true); // Error
PassCar auto;
auto = carRef; // Error
Although the reference carRefpoints to an object of the PassCartype, it is impossi-ble to assign the PassCartype object autoto this object
Trang 8536 C H A P T E R 2 4 T Y P E C O N V E R S I O N I N C L A S S H I E R A R C H I E S
Car
PassCar
carPtr
static_cast<PassCar*>(carPtr)
Pointer to
Base class
Derived class
Downcast
Car
PassCar
static_cast<Car*>(PassCarPtr)
PassCarPtr
Pointer to
Base class
Derived class
Upcast
Downcast
Upcast
Trang 9䊐 Upcasts and Downcasts
Type conversions that walk up a class hierarchy, or upcasts, are always possible and safe.
Upcasting is performed implicitly for this reason
Type conversions that involve walking down the tree, or downcasts, can only be
per-formed explicitly by means of a cast construction The cast operator (type), which was available in C, or the static_cast< >operator are available for this task, and are equivalent in this case
䊐 Explicit Cast Constructions
Given that cabriois again an object of the derived class PassCar, the following state-ments
Example: Car* carPtr = &cabrio;
( (PassCar*) carPtr )->display();
first point the base class pointer carPtrto the cabrioobject.carPtris then cast as a pointer to the derived class This allows you to access the display()method of the derived class PassCar via the pointer Parentheses are necessary in this case as the member access operator ->has a higher precedence than the cast operator (type) The operator static_cast< >conforms to the following
Syntax: static_cast<type>(expression)
and converts the expression to the target type type The previous example is thus equiv-alent to
Example: static_cast<PassCar*>(carPtr)->display();
No parentheses are required here as the operators static_cast<>and->are of equal precedence They are read from left to right
After downcasting a pointer or a reference, the entire public interface of the derived class is accessible
䊐 Downcast Safety Issues
Type conversions from top to bottom need to be performed with great care Downcasting
is only safe when the object referenced by the base class pointer really is a derived class type This also applies to references to base classes
To allow safe downcasting C++ introduces the concept of dynamic casting This
tech-nique is available for polymorphic classes and will be introduced in the next chapter
Trang 10538 C H A P T E R 2 4 T Y P E C O N V E R S I O N I N C L A S S H I E R A R C H I E S
Product
Class hierarchy of products in a supermarket