Here's a commented example which hopefully will show the difference between inheritance and composition.
#include <string>
#include <vector>
#include <iostream>
class Person
{
protected:    
    // a person always has a name and a positive age.
    std::string name;
    unsigned int age; 
public:
    // create the person by giving it a name and an age.
    // A person without name and age mustn't exist.
    Person( std::string _name, unsigned int _age )
    {
        // this is the simplified version to assign member variables...
        // for a better version see class teacher
        name = _name;
        age = _age;
    }
    // return the name, but promise to leave the class and its members intact ("const")
    std::string getName() const
    {
        return name;
    }
    // return the age, but promise to leave the class and its members intact ("const")
    unsigned int getAge() const
    {
        return age;
    }
};
class Student : public Person
{
protected:
    // std::vector is an array of variable length.
    // see 
    std::vector<int> votes; 
public:
    Student( std::string _name, unsigned int _age )
        : Person( _name, _age ) // create the base class - we have to tell it the name and age
    {
        // nothing to do here
    }
    std::vector<int> getVotes() const
    {
        return votes;
    }
    // set the whole "votes" array. This changes the class (respectively the "votes" member) so no "const"
    void setVotes( std::vector<int> _votes )
    {
        votes = _votes;
    }
    // this adds a single vote
    void addVote( int _vote )
    {
        votes.push_back( _vote );
    }
    // this returns the current number of votes
    int getNumVotes() const
    {
        return votes.size();
    }
};
class Teacher : public Person
{
protected:
    unsigned int salary; 
public:
    // a teacher is a person and thus has a name and an age, but also a salary
    Teacher( std::string _name, unsigned int _age, unsigned int _salary )
        : Person( _name, _age ) // create the base class - we have to tell it the name and age
        , salary( _salary ) // here the member salary is set - better method than to do it in the block.
    {
        // nothing to do here
    }
    unsigned int getSalary() const
    {
        return salary;
    }
    void setSalary( unsigned int _salary )
    {
        salary = _salary;
    }
};
// a school class is a standalone class, because it is no person, no teacher, no student.
// But it CONTAINS a teacher and some students.
class Schoolclass
{
private:
    Teacher teacher;
    std::vector<Student> students;
public:
    Schoolclass( Teacher _teacher )
        : teacher(_teacher)
    {
    }
    // this adds a student
    void addStudent( Student _student )
    {
        students.push_back( _student );
    }
    std::vector<Student> getAllStudents() const
    {
        return students;
    }
    Teacher getTeacher() const
    {
        return teacher;
    }
    // now let's return all persons in the school class - this includes both teacher and students
    std::vector<Person> getAllPersons() const {
        // create a vector of persons we can later on return.
        std::vector<Person> result;
        // add the teacher first.
        // Although his class is "Teacher", we can add him to a vector or "Person"s, because he
        // is also a person (Teacher inherits Person). This is one of the benefits of inheritance.
        result.push_back(teacher);
        // Then add all children.
        // We can iterate them.
        for( int i = 0; i<students.size(); i++ )
            result.push_back( students[i] );
        // return the vector of persons.
        return result;
    }
}; 
int main() 
{
    // create a teacher first, because the school class can not exist without teacher.
    Teacher mrSmith( "Smith", 36, 2000 );
    // Then create some students.
    Student tim( "Tim", 12 );
    Student laura( "Laura", 13 );
    Student sam( "Sam", 12 );
    // create the school class with the teacher
    Schoolclass schoolclass( mrSmith );
    // add the students.
    schoolclass.addStudent(tim);
    schoolclass.addStudent(laura);
    schoolclass.addStudent(sam);
    // now let's check it. Print the teacher first.
    std::cout << "Teacher: " << schoolclass.getTeacher().getName();
    std::cout << " Age: " << schoolclass.getTeacher().getAge();
    std::cout << " Salary: " << schoolclass.getTeacher().getSalary() << std::endl << std::endl;
    // Then print all the children.
    std::vector<Student> students = schoolclass.getAllStudents();
    for( int i = 0; i<students.size(); i++ )
    {
        std::cout << "Student: " << students[i].getName();
        std::cout << " Age: " << students[i].getAge() << std::endl;
    }
    std::cout << std::endl;
    float averageAge = 0;
    // get all persons from the class.
    std::vector<Person> allPersons = schoolclass.getAllPersons();
    for( int i=0; i<allPersons.size(); i++ )
    {
        averageAge += allPersons[i].getAge();
    }
    averageAge = averageAge / allPersons.size();
    std::cout << "There are " << allPersons.size() << " persons in the class (including the teacher)" << std::endl;
    std::cout << "Their average age is " << averageAge;
    char c;
    std::cin >> c;
}
Note: At some places it's a bit simplified (e.g. as a trained c++ programmer you would of course hand over strings and vectors as const ref)