Thread: Abstract classes

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    53

    Abstract classes

    If I have to create a .h and .cpp file and I have to work with abstract classes and classes that inherit from the base class. How should I break down the header and cpp file? I'm not sure which goes where and what should be defined in which. It's alittle clearer in java for me.

    Code:
        *  Person - This is an abstract class that will be inherited by all other classes.
              o Private data:
                    + std::string name
                    + int age
                    + int years_in_college (years of college completed)
                    + enum {male, female} sex
        * Student - A Student is a Person.
              o Private data:
                    + std::string major
                    + bool transfer (true if transferred to UCSB from another college or university)
        * Employee - An Employee is a Person.
              o Private data:
                    + std::string department
        * Faculty - A Faculty is an Employee.
              o Private data:
                    + enum {assistant, associate, full} level
        * Staff - A Staff is an Employee.
              o Private data:
                    + enum {fulltime, parttime} status
        * GradStudent - A GradStudent is a Student.
              o Private data:
                    + enum {masters, PhD} degree
        * Dean - A Dean is a Faculty.
              o Private data:
                    + enum {grad, bren, education, CCS, Engr, LS} division
        * Chancellor - A Chancellor is a Faculty.
              o Private data:
                    + bool CameFromUC
    Every class has a function called "void Print()" which prints out a message describing everything known about the class object. Each class also has an inlined function for every private member variable that returns the value of that variable

    Each class has a private static int called "count" which keeps track of how many instantiations of the class there are. The static function "int& Count()" returns the value of the static variable "count" - since it uses a reference return type, this can also be used to set the value of "count", like this: Count() = 0. This static variable is used to ensure that no more than 1 Chancellor is instantiated, no more than 6 deans, and no more than N people overall, where N is specified by the programmer at the beginning of the main() function like this:


    If someone can give me a qucik template of what needs to go where that would be most grateful. Our professor hasn't done a good job explainging classes and how they are created and called.

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    You seem to be off to a good start. Take a look at the tutorials here: http://www.cprogramming.com/tutorial.html (in particular, 12, 19, and 20).

    Those should get you going on the syntax that you'll need.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    .h files usually list a class declaration.

    .cpp files usually contain the implementation or definitions of the class methods.

    You can allocate one class per .h file and .cpp file.

    Your .cpp files need to #include their corresponding header files, e.g.

    //Teacher.cpp

    #include "Teacher.h"

    And, the file with main() in it should also #include the header files of any class name listed on the page:

    //main.cpp

    #include "Teacher.h"
    #include "Student.h"
    etc.

    You can also check out this thread for examples of how to organize multifile programs:

    http://cboard.cprogramming.com/showt...multiple+files
    Last edited by 7stud; 05-26-2005 at 02:40 AM.

  4. #4
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    Here is what I have so far as my sources, sorry if its alittle long.

    school.h
    Code:
    #include <iostream>
    using namespace std;
    
    typedef enum {male, female} SEX;
    typedef enum {assistant, associate, full} LEVEL;
    typedef enum {fulltime, parttime} STATUS;
    typedef enum {masters, PhD} DEGREE;
    typedef enum {grad, bren, education, CCS, Engr, LS} DIVISION;
    
    class Person {
    private:
      static int count;
      static int maxcount;
      string name;
      int age;
      int years_in_college;
      SEX sex;
    public:
      Person(string name, int age, int years_in_college, SEX sex);
      ~Person();
      virtual void Print() = 0;
      static int& Count();
      static int& MaxCount();
      string Name() { return name; }
      int Age() { return age; }
      int Years_in_college() { return years_in_college; }
      SEX Sex() { return sex; }
    };
    
    class Student : public Person {
    private:
      string major;
      bool transfer;
      static int count;
      static int maxcount;
    public:
      Student(string name, int age, int years_in_college, SEX sex, string major, bool transfer);
      ~Student();
      static int& Count();
      static int& MaxCount();
      void Print();
      string Major() { return major; }
      bool Transfer() { return transfer; }
    };
    /*
    class Employee : public Person {
    private:
      //...
    public:
      //...
    };
    
    class Faculty : public Employee {
    private:
      //...
    public:
      //...
    };
    
    class Staff : public Employee {
    private:
      //...
    public:
      //...
    };
    
    class GradStudent : public Student {
    private:
      //...
    public:
      //...
    };
    
    class Dean : public Faculty {
    private:
      //...
    public:
      //...
    };
    
    class Chancellor : public Faculty {
    private:
      //...
    public:
      //...
    };
    */
    void Initialize(int max);
    void PrintCounts();
    schoo.cpp
    Code:
    #include "ucsb.h"
    
    /******************************************************************
    *
    *	Person Abstract CLass
    *
    ********************************************************************/
    
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
      if (Count() >= MaxCount()) {
    
        //code
      }
    
      Count() += 1;
    }
    
    /******************************************************************
    *
    *   Student is a Person
    *
    ********************************************************************/
    
    Student::Student(string name, int age, int years_in_college, SEX sex, 
    		 string major, bool transfer) : Person(name, age, years_in_college, sex)
    {
      
      Count() += 1;
    }
    
    void Student::Print()
    {
      cout << "Info:\n"; 
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tMajor: " << Major() << endl;
      cout << "\tTransfer: " << Transfer() << endl; 
    }
    
    /******************************************************************
    *
    *   Employee is a Person
    *
    ********************************************************************/
    
    Employee::Employee(string name, int age, int years_in_college, SEX sex,
    		   string department) : Person(name, age, years_in_college, sex)
    {
      Count() += 1;
    }
    
    void Employee::Print()
    {
      cout << "Info:\n";
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tDepartment: " << Department() << endl;
      cout << "\tStatus: " << Status() << endl;
    }
    
    /******************************************************************
    *
    *   Faculty is a Employee
    *
    ********************************************************************/
    
    Faculty::Faculty(string name, int age, int years_in_college, SEX sex,
    		 string department, LEVEL level) : Employee(name, age, years_in_college, sex, department)
    {
      Count() += 1;
    }
    
    /******************************************************************
    *
    *   Staff is a Employee
    *
    ********************************************************************/
    
    Staff::Staff(string name, int age, int years_in_college, SEX sex,
             string department, STATUS status) : Employee(name, age, years_in_college, sex, department)
    {
      Count() += 1;
    }
    
    /******************************************************************
    *
    *   GradStudent is a Student
    *
    ********************************************************************/
    
    
    GradStudent::GradStudent(string name, int age, int years_in_college, SEX sex, 
    			 string major, bool transfer, DEGREE degree)
      : Student(name, age, years_in_college, sex, major, transfer)
    {
      Count() += 1;
    }
    
    /******************************************************************
    *
    *   Dean is a Faculty
    *
    ********************************************************************/
    
    Dean::Dean(string name, int age, int years_in_college, SEX sex,
    	   string department, LEVEL level, DIVISION division)
      : Faculty(name, age, years_in_college, sex, department, level)
    {
      Count() += 1;
    }
    
    /******************************************************************
    *
    *   Chancellor is a Faculty
    *
    ********************************************************************/
    
    Chancellor::Chancellor(string name, int age, int years_in_college, SEX sex,
    		       string department, LEVEL level, bool cameFromUCSB)
      : Faculty(name, age, years_in_college, sex, department, level)
    {
      Count() += 1;
    }
    
    void Initialize(int max)
    {
      Person::MaxCount() = max;
      Person::Count() = 0;
      Student::Count() = 0;
      Employee::Count() = 0;
      Staff::Count() = 0;
      Faculty::Count() = 0;
      GradStudent::Count() = 0;
      Dean::Count() = 0;
      Chancellor::Count() = 0;
    }
    
    void PrintCounts()
    {
      cout << "Person: " << Person::Count() << endl;
      cout << "Student: " << Student::Count() << endl;
      cout << "Employee: " << Employee::Count() << endl;
      cout << "Staff: " << Staff::Count() << endl;
      cout << "Faculty: " << Faculty::Count() << endl;
      cout << "GradStudent: " << GradStudent::Count() << endl;
      cout << "Dean: " << Dean::Count() << endl;
      cout << "Chancellor: " << Chancellor::Count() << endl;
      cout << endl;
    }
    
    // Here put the declarations of the static "count" variables
    int Person::count;
    int Person::maxcount;
    int Student::count;
    int Student::maxcount;
    int Employee::count;
    int Employee::maxcount;
    int Staff::count;
    int Staff::maxcount;
    int Faculty::count;
    int Faculty::maxcount;
    int GradStudent::count;
    int GradStudent::maxcount;
    int Dean::count;
    int Dean::maxcount;
    int Chancellor::count;
    int Chancellor::maxcount;
    Every non-abstract class has a function called "void Print()" which prints out a message describing everything known about the class object (see examples below). Each class also has an inlined function for every private member variable that returns the value of that variable (the function name is the variable name with the first letter capitalized).

    Each class has a private static int called "count" which keeps track of how many instantiations of the class there are. The static function "int& Count()" returns the value of the static variable "count" - since it uses a reference return type, this can also be used to set the value of "count", like this: Count() = 0. This static variable is used to ensure that no more than 1 Chancellor is instantiated, no more than 6 deans, and no more than N people overall, where N is specified by the programmer at the beginning of the main() function like this:
    Code:
        int main(int argc, char **argv)
    
        {
    
            Initialize(100); // In this case, N = 100
    
            ...
    
        }
    I've tried to code as much as I can in the school.cpp file, but I'm alittle lost on how start off the actual coding to keep track of whos who. I know that every object will inherit from the one above, but the constructor definitions is giving me some trouble. If someone can give me an example of Student to start me off that would help a lot. Thank you

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Don't quite know what you are asking for but... I would suggest a wrapper that holds an array of up to N pointers to type Person. This wrapper would have methods in it AddChancellor, AddDean, etc... that would check how many of that type you were already are storing:

    Code:
    template<int numpersons=100>
    class University
    {
        Person* person[numpersons];  // Array of "numpersons" people
        int count;                   // Current number of filled slots in "person" array
    public:
        University() : count(0) {}
        ~University()
        {
            for( int i = 0; i < count; ++i )
                delete person[i];
        }
        void AddChancellor()
        {
            if( count >= numpersons )
                cerr << "Error: Can't add any more people, University is full." << endl; 
            else if( Chancellor::Count() >= Chancellor::MaxCount() )
                cerr << "Error: Maximum number of chancellors already met." << endl;
            else 
            {
                cout << "Adding Chancellor to University." << endl;
                // Get info for adding a new chancellor from user
                person[count++] = new Chancellor(...);  // Fill in the blanks with info from user
            }
        }
    };
    
    ...
    
    int main()
    {
        University<> univ;     // Create University obj to store max of 100 people
    
        univ.AddChancellor();  // Add a chancellor to the University
        univ.AddChancellor();  // Should display the "Max Chancellors met" error message
    
        ...
    
    }
    [edit]Or use an STL container instead of an array.[/edit]
    Last edited by hk_mp5kpdw; 05-26-2005 at 01:36 PM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    We haven't gone into advanced topics such as wrappers and stl libs. Maybe the test program we are given will shed some light.

    Code:
    #include "school.h"
      
    int main()
    {
      Initialize(10); // No more than 10 people
    
      // Plus 3
      Student *sp1 = new Student("Joe Smith", 20, 2, male, "CS", false);
      Student *sp2 = new Student("Mike Jones", 20, 2, male, "CS", true);
      Student *sp3 = new Student("Hannah Reed", 21, 3, male, "CS", false);
    
      // Minus 3
      delete sp1;
      delete sp2;
      delete sp3;
    
      Student s1("Jules Adams", 21, 1, male, "CS", false);
      Student s2("Kelly Kennedy", 22, 4, female, "Psychology", false);
      Staff st1("Marge Staff", 50, 4, female, "CS", fulltime);
      Faculty f1("Albert Einstein", 45, 10, male, "CS", associate);
      Faculty f2("Raj Suri", 45, 10, male, "CS", full);
      GradStudent g1("Roger Feris", 31, 8, male, "CS", false, PhD);
      GradStudent g2("Tian Chang", 31, 7, female, "CS", false, PhD);
      Dean d1("Matt Tirrell", 53, 10, male, "ChemE", full, Engr);
      Dean d2("David Marshall", 53, 10, male, "English", full, LS);
      Chancellor c1("Henry Yang", 59, 10, male, "MechE", full, false);
     
      PrintCounts();
    
      s1.Print();
      st1.Print();
      f1.Print();
      g1.Print();
      d1.Print();
      c1.Print();
    
      return 0;
    }

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Person::Count() = 0;

    Count() is a function, not a variable. You can't assign a value to a function. Try:

    Person::count = 0;

    instead. You should probably decrease the appropriate count when the appropriate destructor is called, too. Otherwise, each time the compiler calls a constructor behind the scenes it will increment the count resulting in spuriously high counts.
    You're only born perfect.

  8. #8
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    In the destructor should it be the following:

    Code:
    Chancellor::Chancellor(string name, int age, int years_in_college, SEX sex,
                   string department, LEVEL level, bool cameFromUCSB)
      : Faculty(name, age, years_in_college, sex, department, level)
    {
      Chancellor::Count() += 1;
    }
    
    Chancellor::~Chancellor()
    {
        this->name = NULL;
        this->age = 0;
        this->years_in_college = 0;
        this->sex = NULL;
        this->department = NULL;
        this->level = NULL;
        this->camFromUCSB = NULL;
        Chancellor::count = Chancellor::Count() - 1;
    }

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by cisokay
    In the destructor should it be the following:

    Code:
    Chancellor::~Chancellor()
    {
        ...
        Chancellor::count = Chancellor::Count() - 1;
    }

    I'd just say:

    Code:
    --Chancellor::count;
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    I think I should scale the program down till I fully understand what is going on in each of the instances of person. I have completed most of the coding and size it down to 1 base/abstract class and then two new inherits from the base. The following is the school.h, schoo.cpp, and test.cpp

    schoo.h
    Code:
    #include <iostream>
    using namespace std;
    
    typedef enum {male, female} SEX;
    
    class Person {
    private:
      static int count;
      static int maxcount;
      string name;
      int age;
      int years_in_college;
      SEX sex;
    public:
      Person(string name, int age, int years_in_college, SEX sex);
      ~Person();
      virtual void Print() = 0;
      static int& Count();
      static int& MaxCount();
      string Name() { return name; }
      int Age() { return age; }
      int Years_in_college() { return years_in_college; }
      SEX Sex() { return sex; }
    };
    
    class Student : public Person {
    private:
      string major;
      bool transfer;
      static int count;
      static int maxcount;
    public:
      Student(string name, int age, int years_in_college, SEX sex, string major, bool transfer);
      ~Student();
      static int& Count();
      static int& MaxCount();
      void Print();
      string Major() { return major; }
      bool Transfer() { return transfer; }
    };
    
    class Employee : public Person {
    private:
      string department;
      static int& count;
      static int& maxcount;
    public:
      Employee(string name, int age, int years_in_college, SEX sex, string department);
      ~Employee();
      static int& Count();
      static int& MaxCount();
      void Print();
      string Department() { return department; }
    };
    
    void Initialize(int max);
    void PrintCounts();


    school.cpp
    Code:
    #include "school.h"
    
    /******************************************************************
    *
    *   Person Abstract CLass
    *
    ********************************************************************/
    
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
      if (Count() >= MaxCount()) {
            cerr << "Error: Can't Add Any More People, MAX has been reached." << endl;
      }
      else
        Count() += 1;
    }
    
    Person::~Person()
    {
        this->name = NULL;
        this->age = 0;
        this->years_in_college = 0;
        this->sex = NULL;
        --Person::count;
    }
    
    /******************************************************************
    *
    *   Student is a Person
    *
    ********************************************************************/
    
    Student::Student(string name, int age, int years_in_college, SEX sex,
             string major, bool transfer) : Person(name, age, years_in_college, sex)
    {
    
      Student::Count() += 1;
    }
    
    Student::~Student()
    {
        this->name = NULL;
        this->age = 0;
        this->years_in_college = 0;
        this->sex = NULL;
        this->major = NULL:
        this->transfer = false;
        --Student::count;
    }
    
    void Student::Print()
    {
      cout << "Info:\n";
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tMajor: " << Major() << endl;
      cout << "\tTransfer: " << Transfer() << endl;
    }
    
    /******************************************************************
    *
    *   Employee is a Person
    *
    ********************************************************************/
    
    Employee::Employee(string name, int age, int years_in_college, SEX sex,
               string department) : Person(name, age, years_in_college, sex)
    {
      Employee::Count() += 1;
    }
    
    Employee::~Employee()
    {
        this->name = NULL;
        this->age = 0;
        this->years_in_college = 0;
        this->sex = NULL;
        this-department = NULL;
        --Employee::count;
    }
    
    void Employee::Print()
    {
      cout << "Info:\n";
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tDepartment: " << Department() << endl;
    }
    
    /****************************************
    *
    *   Global Functions
    *
    *****************************************/
    
    void Initialize(int max)
    {
      Person::MaxCount() = max;
      Person::Count() = 0;
      Student::Count() = 0;
      Employee::Count() = 0;
    }
    
    void PrintCounts()
    {
      cout << "Person: " << Person::Count() << endl;
      cout << "Student: " << Student::Count() << endl;
      cout << "Employee: " << Employee::Count() << endl;
    }
    
    // Here put the declarations of the static "count" variables
    int Person::count;
    int Person::maxcount;
    int Student::count;
    int Student::maxcount;
    int Employee::count;
    int Employee::maxcount;
    test1.cpp
    Code:
    #include "school.h"
    
    int main()
    {
      Initialize(10); // No more than 10 people
    
      // Plus 3
      Student *sp1 = new Student("Joe Smith", 20, 2, male, "CS", false);
      Student *sp2 = new Student("Mike Jones", 20, 2, male, "CS", true);
      Student *sp3 = new Student("Hannah Reed", 21, 3, male, "CS", false);
    
      // Minus 3
      delete sp1;
      delete sp2;
      delete sp3;
    
      Student s1("Jules Adams", 21, 1, male, "CS", false);
      Student s2("Kelly Kennedy", 22, 4, female, "Psychology", false);
      Employee e1("Rick James", 18, 2, male "Math");
      Employee e1("John Doe",54, 5, female, "Pols");
    
      PrintCounts();
    
      s1.Print();
      st1.Print();
    
      return 0;
    }
    When I try to compile I get the following errors:

    Code:
    school.cpp:23: error: invalid conversion from `int' to `SEX'
    school.h: In destructor `Student::~Student()':
    school.h:10: error: `std::string Person::name' is private
    school.cpp:42: error: within this context
    school.h:11: error: `int Person::age' is private
    school.cpp:43: error: within this context
    school.h:12: error: `int Person::years_in_college' is private
    school.cpp:44: error: within this context
    school.h:13: error: `SEX Person::sex' is private
    school.cpp:45: error: within this context
    school.cpp:46: error: ambiguous overload for 'operator=' in '
       this->Student::major = 0'
    /usr/include/c++/3.3.2/bits/basic_string.h:358: error: candidates are:
       std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT,
       _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits,
       _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc =
       std::allocator<char>]
    /usr/include/c++/3.3.2/bits/basic_string.h:361: error:
       std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT,
       _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits =
       std::char_traits<char>, _Alloc = std::allocator<char>]
    /usr/include/c++/3.3.2/bits/basic_string.h:364: error:
       std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT,
       _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits =
       std::char_traits<char>, _Alloc = std::allocator<char>]
    school.cpp:46: error: syntax error before `:' token
    school.h: In destructor `Employee::~Employee()':
    school.h:10: error: `std::string Person::name' is private
    school.cpp:76: error: within this context
    school.h:11: error: `int Person::age' is private
    school.cpp:77: error: within this context
    school.h:12: error: `int Person::years_in_college' is private
    school.cpp:78: error: within this context
    school.h:13: error: `SEX Person::sex' is private
    school.cpp:79: error: within this context
    school.cpp:80: error: no match for 'operator-' in 'this -
       this->Employee::department'
    school.cpp: At global scope:
    school.cpp:120: error: conflicting types for `int Employee::count'
    school.h:45: error: previous declaration as `int&Employee::count'
    school.cpp:121: error: conflicting types for `int Employee::maxcount'
    school.h:46: error: previous declaration as `int&Employee::maxcount'
    Thank you all for your help. Learning a little at a time.

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Code:
    Chancellor::Chancellor(string name, int age, int years_in_college, SEX sex,
    			   string department, LEVEL level, bool cameFromUCSB)
      : Faculty(name, age, years_in_college, sex, department, level)
    {
      Chancellor::count += 1;
    }
    
    Chancellor::~Chancellor()
    { 
       --Chancellor::count;
    }
    I don't think you need the scope resolution operator with explicit declaration of which class count is since each of the above is declared within the class itself, but I KNOW it doesn't hurt to use that level of resolution.
    You're only born perfect.

  12. #12
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    Yea I thought it be best to use this scope to make it clear. I'm just having trouble setting up the constructors. What should be set to what and how it should be set. I've done OOP in JAVA before and for some reason it seems alittle clearer.

    If I wanted to start out with the abstract object, person:
    Code:
    #include "school.h"
    
    /******************************************************************
    *
    *   Person Abstract CLass
    *
    ********************************************************************/
    
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
      if (Count() >= MaxCount()) {
            cerr << "Error: Can't Add Any More People, MAX has been reached." << endl;
      }
      else
        Count() += 1;
    
      //how should person be set when passed in the params ?
    }
    
    Person::~Person()
    {
        Person::name = NULL;
        Person::age = 0;
        Person::years_in_college = 0;
        Person::sex = NULL;
        --Person::count;
    }
    Since you are passed in string name, int age, int years_in_college, SEX sex
    How should these params be set ?

    This->name = name; ?
    name = name; ?
    Person::name = name; ?

    I'm not sure which to use ?

    Also does the destructor look correct from what you've seen so far?

  13. #13
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
        if ( Count() >= MaxCount()) {
            cerr << "Error: Can't Add Any More People, MAX has been reached." << endl;
        }
        else
            Count() += 1;
    
        //how should person be set when passed in the params ?
    }
    The problem with this is you've already constructed an object when you get to the point where you say you can't add any more. That's why you probably would want to use a wrapper class to store all this stuff and validate the counts before you decide to construct an object.

    Within the class itself it is probably easier to just use count and maxcount directly instead of calling the functions Count() and MaxCount(). The functions should probably only be used by the wrapper.

    Quote Originally Posted by cisokay
    Since you are passed in string name, int age, int years_in_college, SEX sex
    How should these params be set ?

    This->name = name; ?
    name = name; ?
    Person::name = name; ?

    I'm not sure which to use ?
    I usually like to differentiate the names of the arguments to the constructor a bit from those of the actual class itself just to help avoid a little confusion. It's also best to use an initializer list when constructing your objects wherever possible. Combining those two ideas you have something like:

    Code:
    Person::Person(string _name, int _age, int _years, SEX _sex) : name(_name),
                                                                   age(_age),
                                                                   years_in_college(_years),
                                                                   sex(_sex)
    {
        ...
    }
    Quote Originally Posted by cisokay
    Code:
    Person::~Person()
    {
        Person::name = NULL;
        Person::age = 0;
        Person::years_in_college = 0;
        Person::sex = NULL;
        --Person::count;
    }
    Also does the destructor look correct from what you've seen so far?
    No, you don't need to do anything special in the destructor except decrement the count:

    Code:
    Person::~Person()
    {
        --count;
    }
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  14. #14
    Registered User
    Join Date
    Apr 2005
    Posts
    53
    I'm still confused about the Person constructor, when you create an instance of another type of person you have to handle it in the person constructor?

    Code:
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
      if (Count() >= MaxCount()) {
            cerr << "Error: Can't Add Any More People, MAX has been reached." << endl;
      }
      else
        //what keeps count of everything ?
        Count() += 1;
    }
    I know some people made post about using a wrapper class/etc. Again I haven't gotten that advanced in our class to use that yet. We've only learned a few things for C++.

    The main program has problems trying to compile, I get errors such as
    Code:
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0x2b): In function `Person::Person[not-in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX)':
    : undefined reference to `Person::MaxCount()'
    ./libschool.a(school.o)(.text+0x63): In function `Person::Person[not-in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX)':
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0xb9): In function `Person::Person[in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX)':
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0xc1): In function `Person::Person[in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX)':
    : undefined reference to `Person::MaxCount()'
    ./libschool.a(school.o)(.text+0xf9): In function `Person::Person[in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX)':
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0x208): In function `Student::Student[not-in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)':
    : undefined reference to `Student::Count()'
    ./libschool.a(school.o)(.text+0x2d8): In function `Student::Student[in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)':
    : undefined reference to `Student::Count()'
    ./libschool.a(school.o)(.text+0x62c): In function `Employee::Employee[not-in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
    : undefined reference to `Employee::Count()'
    ./libschool.a(school.o)(.text+0x6f6): In function `Employee::Employee[in-charge](std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, SEX, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
    : undefined reference to `Employee::Count()'
    ./libschool.a(school.o)(.text+0x98b): In function `Initialize(int)':
    : undefined reference to `Person::MaxCount()'
    ./libschool.a(school.o)(.text+0x997): In function `Initialize(int)':
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0x9a2): In function `Initialize(int)':
    : undefined reference to `Student::Count()'
    ./libschool.a(school.o)(.text+0x9ad): In function `Initialize(int)':
    : undefined reference to `Employee::Count()'
    ./libschool.a(school.o)(.text+0x9cf): In function `PrintCounts()':
    : undefined reference to `Person::Count()'
    ./libschool.a(school.o)(.text+0xa0e): In function `PrintCounts()':
    : undefined reference to `Student::Count()'
    ./libschool.a(school.o)(.text+0xa4d): In function `PrintCounts()':
    : undefined reference to `Employee::Count()'
    collect2: ld returned 1 exit status
    school.cpp
    Code:
    #include "school.h"
    
    /******************************************************************
    *
    *   Person Abstract CLass
    *
    ********************************************************************/
    
    Person::Person(string name, int age, int years_in_college, SEX sex)
    {
    
        this->name = name;
        this->age = age;
        this->years_in_college = years_in_college;
        this->sex = sex;
    
    
      if (Count() >= MaxCount()) {
            cerr << "Error: Can't Add Any More People, MAX has been reached." << endl;
      }
      else
        Count() += 1;
    }
    
    Person::~Person()
    {
        --Person::count;
    }
    
    /******************************************************************
    *
    *   Student is a Person
    *
    ********************************************************************/
    
    Student::Student(string name, int age, int years_in_college, SEX sex,
             string major, bool transfer) : Person(name, age, years_in_college, sex)
    {
    
        name = name;
        age = age;
        years_in_college = years_in_college;
        sex = sex;
        this->major = major;
        this->transfer = transfer;
    
    
      Student::Count() += 1;
    }
    
    Student::~Student()
    {
        --Student::count;
    }
    
    void Student::Print()
    {
      cout << "Info:\n";
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tMajor: " << Major() << endl;
      cout << "\tTransfer: " << Transfer() << endl;
    }
    
    /******************************************************************
    *
    *   Employee is a Person
    *
    ********************************************************************/
    
    Employee::Employee(string name, int age, int years_in_college, SEX sex,
               string department) : Person(name, age, years_in_college, sex)
    {
        name = name;
        age = age;
        years_in_college = years_in_college;
        sex = sex;
        this->department = department;
    
    
      Employee::Count() += 1;
    }
    
    Employee::~Employee()
    {
        --Employee::count;
    }
    
    void Employee::Print()
    {
      cout << "Info:\n";
      cout << "\tName: " << Name() << endl;
      cout << "\tAge: " << Age() << endl;
      cout << "\tYears in college: " << Years_in_college() << endl;
      cout << "\tSex: " << Sex() << endl;
      cout << "\tDepartment: " << Department() << endl;
    }
    
    /****************************************
    *
    *   Global Functions
    *
    *****************************************/
    
    void Initialize(int max)
    {
      Person::MaxCount() = max;
      Person::Count() = 0;
      Student::Count() = 0;
      Employee::Count() = 0;
    }
    
    void PrintCounts()
    {
      cout << "Person: " << Person::Count() << endl;
      cout << "Student: " << Student::Count() << endl;
      cout << "Employee: " << Employee::Count() << endl;
    }
    
    // Here put the declarations of the static "count" variables
    int Person::count;
    int Person::maxcount;
    int Student::count;
    int Student::maxcount;
    int Employee::count;
    int Employee::maxcount;
    school.h
    Code:
    #include <iostream>
    using namespace std;
    
    typedef enum {male, female} SEX;
    
    class Person {
    private:
      static int count;
      static int maxcount;
      string name;
      int age;
      int years_in_college;
      SEX sex;
    public:
      Person(string name, int age, int years_in_college, SEX sex);
      ~Person();
      virtual void Print() = 0;
      static int& Count();
      static int& MaxCount();
      string Name() { return name; }
      int Age() { return age; }
      int Years_in_college() { return years_in_college; }
      SEX Sex() { return sex; }
    };
    
    class Student : public Person {
    private:
      string major;
      bool transfer;
      static int count;
      static int maxcount;
    public:
      Student(string name, int age, int years_in_college, SEX sex, string major, bool transfer);
      ~Student();
      static int& Count();
      static int& MaxCount();
      void Print();
      string Major() { return major; }
      bool Transfer() { return transfer; }
    };
    
    class Employee : public Person {
    private:
      string department;
      static int& count;
      static int& maxcount;
    public:
      Employee(string name, int age, int years_in_college, SEX sex, string department);
      ~Employee();
      static int& Count();
      static int& MaxCount();
      void Print();
      string Department() { return department; }
    };
    
    void Initialize(int max);
    void PrintCounts();
    I've added the required code that has been posted on here and this is my latest source code trying to run test1.cpp

    test1.cpp
    Code:
    #include "school.h"
    
    int main()
    {
      Initialize(10); // No more than 10 people
    
      // Plus 3
      Student *sp1 = new Student("Joe Smith", 20, 2, male, "CS", false);
      Student *sp2 = new Student("Mike Jones", 20, 2, male, "CS", true);
      Student *sp3 = new Student("Hannah Reed", 21, 3, male, "CS", false);
    
      // Minus 3
      delete sp1;
      delete sp2;
      delete sp3;
    
      Student s1("Jules Adams", 21, 1, male, "CS", false);
      Student s2("Kelly Kennedy", 22, 4, female, "Psychology", false);
      Employee e1("Rick James", 18, 2, male "Math");
      Employee e1("John Doe",54, 5, female, "Pols");
    
      PrintCounts();
    
      s1.Print();
      st1.Print();
    
      return 0;
    }
    Last edited by cisokay; 05-26-2005 at 08:13 PM.

  15. #15
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Well, I don't see anywhere where you've actually coded any of the Count() or MaxCount() functions. Sure you've defined them but where is the actual code?

    Also, you need to check that a count is less than the maxcount for whatever object you're trying to create before you call its constructor because once you call the constructor you've just built another object of that type even if you don't end up incrementing the count because of the if/else code. To do that, I suggested a wrapper that has code which checks for these conditions before the actual constructor gets called. You don't really need a wrapper, but you do need code of some sort that surrounds all the constructor calls that performs such a check.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Issue with abstract classes
    By DavidP in forum C# Programming
    Replies: 1
    Last Post: 08-18-2008, 03:03 PM
  2. Operators of abstract classes
    By Thanuja91 in forum C++ Programming
    Replies: 1
    Last Post: 11-02-2007, 05:30 AM
  3. Replies: 7
    Last Post: 03-10-2004, 04:10 PM
  4. Abstract classes and operators
    By ygfperson in forum C++ Programming
    Replies: 11
    Last Post: 06-10-2003, 10:50 PM
  5. Purpose of Abstract Classes
    By luckygold6 in forum C++ Programming
    Replies: 15
    Last Post: 04-29-2003, 06:24 PM