Single inheritance polymorphism I am learning about polymorphism in C++ and decided to implement an example. Is there anything I need to fix in my code? This compiles and runs. 

#include &lt;iostream&gt;


using std::cout;
using std::endl;
using std::cin;


class Employee
{
public:
    Employee():salary(1000){}
    virtual ~Employee(){}
    virtual void Talk() const {cout &lt;&lt; "Employee says: ";}

protected:
    int salary;
};

class Programmer : public Employee
{
public:
    void Talk() const {cout &lt;&lt; "I am a Programmer.\n";}
    void Compiling() const {cout &lt;&lt; "My code is compiling...\n";}
};

class SalesPerson : public Employee
{
public:
    void Talk() const {cout &lt;&lt; "I am a SalesRep.\n";}
    void Selling() const {};
};


int main()
{
    const int numEmployees = 3;
    Employee* Company[numEmployees];
    Employee* pEmployee;

    int choice,i;

    for(i=0; i&lt;numEmployees; i++)
    {
        std::cout &lt;&lt; "(1) Programmer (2) SalesRep: ";
        cin &gt;&gt; choice;
        if(choice == 1)
            pEmployee = new Programmer;
        else
            pEmployee = new SalesPerson;

        Company[i] = pEmployee;
    }

    cout &lt;&lt; endl;

    for(i = 0; i&lt;numEmployees;i++)
    {
        Company[i]-&gt;Talk();

        Programmer *pCoder = dynamic_cast&lt;Programmer *&gt; (Company[i]);

        if(pCoder)
            pCoder-&gt;Compiling();


        cout &lt;&lt; endl;
    }

    return 0;
}
Problems with your interface design:

The Employee interface you've designed is clearly lacking
abstraction, since you have a dynamic_cast in the program to
test if an employee is of a specific type. 

Employee should instead have a virtual method such as DoWork()
which in turn will call Compiling() for Programmer,
Selling for a SalesPerson and so forth:

class Employee 
{
public:
    ....

    // Virtual function with no default implementation (= 0)
    virtual void DoWork() const = 0;
};

class Programmer 
{
public:
    void DoWork() const { Compiling(); }
};

class SalesPerson
{
public:
    void DoWork() const { Selling(); }
};


The constructor of Employee sets salary to 1000 unconditionally.
Perhaps it would be better to take salary as a constructor parameter 
so you can easily specify different salaries:

Employee(double salary) : salary(salary) { }


BTW, double seems more appropriate for a monetary value, as it
is likely to include decimal places. int is for whole numbers only.

The destructor of Employee is empty, so it should be made a default:

virtual ~Employee() = default;


Memory management tidbits:

It is generally better to avoid manual memory management, as it is
error prone, not exception safe, and slipping a memory leak is very easy.
In fact, in your current example, the objects you've allocated
with new are not being destroyed. Remember that C++ is not garbage collected. You would have to delete them somewhere.

You should ideally be using an automatic pointer to manage
your dynamic instances. main() could be reworked in the following way:

#include &lt;array&gt;
#include &lt;memory&gt;

int main()
{
    std::array&lt;std::unique_ptr&lt;Employee&gt;, 3&gt; company;

    int choice = 0;
    for (int i = 0; i &lt; company.size(); i++)
    {
        std::cout &lt;&lt; "(1) Programmer (2) SalesRep: ";
        cin &gt;&gt; choice;

        if (choice == 1)
        {
            company[i].reset( new Programmer );
        }
        else
        {
            company[i].reset( new SalesPerson );
        }
    }

    ....
}


You should note in the example above the use of std::unique_ptr and
std::array. The unique_ptr is a managed pointer that will delete
the object automatically when you leave the function scope. This way
you don't have to worry about memory leaks. std::array is a fixed size
array which behaves just like a plain C array, but with some extra member
methods and debug bounds checking. It also knows its length, so we no longer
need to keep that numEmployees constant around.