15.3. Conversions and Inheritance

15.3.1. Derived-to-Base Conversions
If we have an object of a derived type, we can use its address to assign or initialize a pointer to the base type. Similarly, we can use a reference or object of the derived type to initialize a reference to the base type. Pedantically speaking, there is no similar conversion for objects. The compiler will not automatically convert an object of derived type into an object of the base type.It is, however, usually possible to use a derived-type object to initialize or assign an object of base type. The difference between initializing and/or assigning an object and the automatic conversion that is possible for a reference or pointer is subtle and must be well understood.
Conversion to a Reference is Not the Same as Converting an Object
As we've seen, we can pass an object of derived type to a function expecting a reference to base. We might therefore think that the object is converted. However, that is not what happens. When we pass an object to a function expecting a reference, the reference is bound directly to that object. Although it appears that we are passing an object, the argument is actually a reference to that object. The object itself is not copied and the conversion doesn't change the derived-type object in any way. It remains a derived-type object.When we pass a derived object to a function expecting a base-type object (as opposed to a reference) the situation is quite different. In that case, the parameter's type is fixedboth at compile time and run time it will be a base-type object. If we call such a function with a derived-type object, then the base-class portion of that derived object is copied into the parameter.It is important to understand the difference between converting a derived object to a base-type reference and using a derived object to initialize or assign to a base-type object.
Using a Derived Object to Initialize or Assign a Base Object
When we initialize or assign an object of base type, we are actually calling a function: When we initialize, we're calling a constructor; when we assign, we're calling an assignment operator.When we use a derived-type object to initialize or assign a base object, there are two possibilities. The first (albeit unlikely) possibility is that the base class might explicitly define what it means to copy or assign an object of the derived type to an object of the base type. It would do so by defining an appropriate constructor or assignment operator:
In this case, the definition of these members would control what happens when a Derived object is used to initialize or assign to a Base object.However, it is uncommon for classes to define explicitly how to initialize or assign an object of the base type from an object of derived type. Instead, base classes ususally define (either explicitly or implicitly) their own copy constructor and assignment operator (Chapter 13). These members take a parameter that is a (const) reference to the base type. Because there is a conversion from reference to derived to reference to base, these copy-control members can be used to initialize or assign a base object from a derived object:
class Derived;
class Base {
public:
Base(const Derived&); // create a new Base from a Derived
Base &operator=(const Derived&); // assign from a Derived
// ...
};
When we call the Item_base copy constructor or assignment operator on an object of type Bulk_item, the following steps happen:
Item_base item; // object of base type
Bulk_item bulk; // object of derived type
// ok: uses Item_base::Item_base(const Item_base&) constructor
Item_base item(bulk); // bulk is "sliced down" to its Item_base portion
// ok: calls Item_base::operator=(const Item_base&)
item = bulk; // bulk is "sliced down" to its Item_base portion
Accessibility of Derived-to-Base Conversion
Like an inherited member function, the conversion from derived to base may or may not be accessible. Whether the conversion is accessible depends on the access label specified on the derived class' derivation.

15.3.2. Conversions from Base to Derived
There is no automatic conversion from the base class to a derived class. We cannot use a base object when a derived object is required:
The reason that there is no (automatic) conversion from base type to derived type is that a base object might be just thata base. It does not contain the members of the derived type. If we were allowed to assign a base object to a derived type, then we might attempt to use that derived object to access members that do not exist.What is sometimes a bit more surprising is that the restriction on converting from base to derived exists even when a base pointer or reference is actually bound to a derived object:
Item_base base;
Bulk_item* bulkP = &base; // error: can't convert base to derived
Bulk_item& bulkRef = base; // error: can't convert base to derived
Bulk_item bulk = base; // error: can't convert base to derived
The compiler has no way to know at compile time that a specific conversion will actually be safe at run time. The compiler looks only at the static types of the pointer or reference to determine whether a conversion is legal.In those cases when we know that the conversion from base to derived is safe, we can use a static_cast (Section 5.12.4, p. 183) to override the compiler. Alternatively, we could request a conversion that is checked at run time by using a dynamic_cast, which is covered in Section 18.2.1 (p. 773).
Bulk_item bulk;
Item_base *itemP = &bulk; // ok: dynamic type is Bulk_item
Bulk_item *bulkP = itemP; // error: can't convert base to derived