# More about Inheritance

### Function Hiding

In the following example, class _Base_ has two overloaded member functions _show()_ and _show(int)_. Class _Derived_ inherit from _Base_, and has a member function _show()_.

```cpp
class Base {
public:
    Base(int data = 10) : ma(data) {}
    void show() {
        cout << "Base::show()" << endl;
    }
    void show(int) {
        cout << "Base::show(int)" << endl;
    }
protected:
    int ma;
};
​
class Derived : public Base {
public:
    Derived(int data = 20) : Base(data), mb(data) {}
    void show() {
        cout << "Derived::show()" << endl;
    }
private:
    int mb;
};
```

Now in the main function we defined an object of class _Derived_. But when the function _show(int)_ is called, an error occurs. Since _Derived_ inherits _show(int)_ from _Base_, why can't the compiler find it?

```cpp
int main() {
    Derived d;
    d.show();   // Derived::show()
    d.show(10); // ERROR
    return 0;
}
```

Notice that when a member function is called, the compiler first search for it inside the derived class itself. Only if no definition is found within this scope does the compiler goes inside the base class. In this case, function _Derived::show()_ hides the functions with the same name _Base::show()_ and _Base::show(int)_, which is called **function hiding**. To fix this, we may use `d.Base::show(10)` to call the corresponding function within the scope of _Base_.

Notice that function hiding refers to the hiding of functions with the same name defined **in different scopes**, which is very different from function overloading. Recall that the definition of **function overloading** is that, there are functions **in the same scope** whose names are the same, but their parameter lists are different. In the example above, _Base::show()_ and _Base::show(int)_ are a couple of overloaded functions.

### Conversions of Base and Derived

Can a base class and a derived class be converted into each other? Let's see the following example:

```cpp
int main() {
    Base b(10);
    Derived d(20);
    b = d;  // Yes
    d = b;  // No
    return 0;
}
```

Here we defined a _Base_ object and a _Derived_ object. Assume we have overloaded operator `=`, then it is valid to assign _Derived_ to _Base_, but invalid to assign _Base_ to _Derived_.

Object pointers are similar:

```cpp
int main() {
    Base b(10);
    Derived d(20);
    Base *pb = &d;  // Yes
    pb->show(); // Base::show()
    Derived *pd = &b;   // No
    return 0;
}
```

Here we can let a _Base_ pointer pointing to a _Derived_ object, but not vice versa. Moreover, if we use a _Base_ pointer which points to a _Derived_ object, we can only access the members of _Base_. It is able to compile if we force a _Derived_ pointer to point to a _Base_ object using type conversion `Derived *pd = (Derived *)&b`, but it is unsafe, since there is not actually a _Derived_ object, which may involve illegal memory access.

In all, in inheritance, only type conversion from bottom (base class) to top (derived class) is supported. Since derived class is a type of base class, which means that a base class is more generic, it make sense if we use something generic to point to something specific, but not the other wa
