Thread: Making a human class...not sure what to do

  1. #16
    Codigious FingerPrint's Avatar
    Join Date
    Mar 2006
    Posts
    60
    I came up with this. It doesnt say Male or Female, but it will shows M or F which stand for male and female.

    Code:
    do{
            cout << "\n\n Gender: Male(1) or Female(2)\n\n";
            cin >> gen;
            if(gen == 1){
                   human.setGender('M');
                   }
            else if(gen == 2){
                 human.setGender('F');
                 }
        }while(0);
         // Some cout's here...that'ss about it
    That part works fine. lol, but now I cant figure out a way to allow the user to input their age and it set the age that way(using the class). Not using the class its super simple. But I want to be able to get input from the user and have it set human.setAge( their input here ). If you get what im saying, anyone wanna help me out?

    Thanks for posts too guys. Im gonna mess around with what you guys said above, so I have a little better understanding of how to do the gender part and classes in general.
    Code:
    /* ------------------------------------------------------------------*/
                               // INSERT CODE HERE
    /* ------------------------------------------------------------------*/

  2. #17
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Setting age or any other property should be no different, except you use an appropriate data type.

  3. #18
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    > What is wrong with bool? You don't like that it uses only 1 single bit?

    An enum is probably preferable just because it is cleaner and more strongly-typed. Of course, with enums you can't specify the size, and I believe they are only guaranteed to be at least large enough to hold all the values (up to the maximum value of an int). Basically, look at these examples:
    Code:
    enum gender { MALE, FEMALE };
    gender foo = true; //error
    foo = 1; //error
    foo = MALE; //OK
    
    //or
    
    typedef bool gender;
    const gender MALE = 1;
    const gender FEMALE = 0;
    
    gender foo = true; //no error
    foo = 1; //no error
    foo = MALE;
    At the very least, an enum would help prevent confusion.

    Also, I believe the sizeof(bool) is implementation specific (usually 1 byte, possibly more)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  4. #19
    Codigious FingerPrint's Avatar
    Join Date
    Mar 2006
    Posts
    60
    >>Setting age or any other property should be no different, except you use an appropriate data type.

    Well I dont see how I could use an if statement toaccept every possible age. The only way I can think of doing it would calle for like 100 else if's heh. Like I said in my first post, "im such a noob".
    Code:
    /* ------------------------------------------------------------------*/
                               // INSERT CODE HERE
    /* ------------------------------------------------------------------*/

  5. #20
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    This code is stupid (and can have some bugs in it), because it doesn't use standard library date functions but it's a very good "reading" for newbies. The only thing that makes this kind of date functions difficult is 29th of February.
    Code:
    #define MALE false
    #define FEMALE true
    #define MONTH false
    #define DAY true
    #include <ctime>
    #include <iostream>
    
    class Human{
    	public:
    		void setGender(bool tmpgender){
    			Gender=tmpgender;
    		}
    		bool getGender(){
    			return Gender;
    		}
    		int DayMonthToDay(int day,int month){
    			int days[12]={31,28,31,30,31,30,31,31,30,31,30,31},count=0;
    			if((getAgeInfo('Y')-1970)%4==0){
    				days[1]=29;
    			}
    			for(int i=1;i<month%13;i++){
    				count+=days[i-1];
    			}
    			count+=day;
    			return count;
    		}
    		int DateDataFromDay(int day,bool dayt){
    			int days[12]={31,28,31,30,31,30,31,31,30,31,30,31},i;
    			if((getAgeInfo('Y')-1970)%4==0){
    				days[1]=29;
    			}
    			for(i=0;day>days[i];i++){
    				day-=days[i];
    			}
    			if(dayt){ return day; }
    			return i+1;
    		}
    		void setBirthTime(int year,int month,int day,int hour,int minute,int second){
    			setAgeInfo('y',year);
    			setAgeInfo('d',DayMonthToDay(day,month));
    			setAgeInfo('h',hour);
    			setAgeInfo('m',minute);
    			setAgeInfo('s',second);
    		}
    		void setAgeInfo(char type,int tmpstamp){
    			int temporary;
    			switch(type){
    				//set the day of birth
    				case 'd':
    					if(tmpstamp<=366){
    						TimeStamp-=getAgeInfo('D')*3600*24;
    						TimeStamp+=tmpstamp*3600*24/*+((getAgeInfo('Y')-1970)/4)*3600*24*/;
    					}
    					return;
    				//set the hour of birth
    				case 'h':
    					TimeStamp-=getAgeInfo('H')*3600;
    					TimeStamp+=(tmpstamp%24)*3600;
    					return;
    				//set the minute of birth
    				case 'm':
    					TimeStamp-=getAgeInfo('H')*60;
    					TimeStamp+=(tmpstamp%60)*60;
    					return;
    				//set the total seconds of birth (since 1970)
    				case 'r':
    					TimeStamp=tmpstamp;
    					return;
    				//set the seconds of birth
    				case 's':
    					TimeStamp-=getAgeInfo('H');
    					TimeStamp+=(tmpstamp%60);
    					return;
    				//set the year of birth
    				case 'y':
    					temporary=(getAgeInfo('Y')-1970)*(3600*24*365);
    					TimeStamp-=(getAgeInfo('Y')-1970)*(3600*24*365)+((getAgeInfo('Y')-1970)/4)*3600*24;
    					TimeStamp+=(tmpstamp-1970)*3600*24*365+((tmpstamp-1970)/4)*3600*24;
    					return;	
    			}
    		}
    		int getAgeInfo(char type){
    			int tmpint;
    			switch(type){
    				//get the day of birth
    				case 'D':
    					return (TimeStamp/(3600*24)%365)-TimeStamp/(3600*24*365)/4;
    				//get the day of age
    				case 'd':
    					tmpint=time(NULL)-TimeStamp;
    					return (tmpint/(3600*24)%365)-tmpint/(3600*24*365)/4;
    				//hours of age
    				case 'h':
    					tmpint=time(NULL)-TimeStamp;
    					return (tmpint%(3600*24))/3600;
    				//hour of birth
    				case 'H':
    					return (TimeStamp%(3600*24))/3600;
    				//minutes of age
    				case 'm':
    					tmpint=time(NULL)-TimeStamp;
    					return (tmpint%3600)/60;
    				//minutes of birth
    				case 'M':
    					return (TimeStamp%3600)/60;
    				//total seconds of age
    				case 'r':
    					return tmpint=time(NULL)-TimeStamp;
    				//total seconds of birth (since 1970)
    				case 'R':
    					return TimeStamp;
    				//seconds of age
    				case 's':
    					tmpint=time(NULL)-TimeStamp;
    					return tmpint%60;
    				//seconds of birth
    				case 'S':
    					return TimeStamp%60;
    				//year of age
    				case 'y':
    					tmpint=time(NULL)-TimeStamp;
    					tmpint=tmpint/(3600*24);
    					tmpint+=tmpint/365/4;
    					return tmpint/365;
    				//year of birth
    				case 'Y':
    					tmpint=TimeStamp/(3600*24);
    					tmpint+=tmpint/365/4;
    					return (tmpint/365)+1970;
    				default:
    					return 0;
    			}
    		}
    	private:
    		bool Gender;
    		int TimeStamp;
    };
    
    int main(){
    	Human user;
    	char gender[256];
    	int year=0,month=0,day=0,hour=0,minute=0,second=0;
    	do{
    	std::cin.clear();
    	std::cout<<"Please enter M or F as your gender\n";
    	std::cin.getline(gender,256,'\n');
    	}while(gender[0]!='m' && gender[0]!='f');
    	if(gender[0]=='m'){
    		user.setGender(MALE);
    	}
    	else{
    		user.setGender(FEMALE);
    	}
    	do{
    	std::cin.clear();
    	std::cout<<"Please enter your year of birth\n";
    	std::cin>>year;
    	}while(year<1970||year>3000);
    	do{
    	std::cin.clear();
    	std::cout<<"Please enter your month of birth\n";
    	std::cin>>month;
    	}while(month<1||month>12);
    	do{
    	std::cin.clear();
    	std::cout<<"Please enter your day of birth\n";
    	std::cin>>day;
    	}while(day<1||day>31);
    	user.setBirthTime(year,month,day,hour,minute,second);
    	if(user.getGender()==MALE){
    		strcpy(gender,"male");
    	}
    	else{
    		strcpy(gender,"female");
    	}
    	printf("You are %i years, %i months, %i days, %i hours, %i minutes and %i seconds old.\nYou are %s\n\n",
    		user.getAgeInfo('y'),user.DateDataFromDay(user.getAgeInfo('d'),MONTH),user.DateDataFromDay(
    		user.getAgeInfo('d'),DAY),user.getAgeInfo('h'),user.getAgeInfo('m'),user.getAgeInfo('s'),gender);
    	system("PAUSE");
    }
    Last edited by maxorator; 10-08-2006 at 07:01 AM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  6. #21
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    What is wrong with bool? You don't like that it uses only 1 single bit?
    Everything. It would be ok to have a bool for two vars representing male or female but not one. An enum is the best option and also provides for future expansion. I don't think storing 1 bit, 8 bits, 16 bits, or even 32 bits in the class is going to hurt anything.

    Hell you could store 64 bits and use each bit as a gene, but that's getting a bit deep. No pun intended.

  7. #22
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    The only thing, that was actually an answer to my question was "Everything." and that's not enough. Then you tell where you would use it: "It would be...". Now you tell, what you would use instead: "An enum is the...". Can you give a correct answer? I want to know, why you don't like it, but you haven't told me.

    BTW, what do you think of the age/date thing?
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  8. #23
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Well I dont see how I could use an if statement toaccept every possible age. The only way I can think of doing it would calle for like 100 else if's heh. Like I said in my first post, "im such a noob".
    Your Human object would accept any age as a variable. Well, you may do some checking (e.g for negative numbers), but that might be done inside the setAge method (a Human should know that it's age can't be smaller than 0).

    Code:
    int age = anything;
    human.setAge(age);
    Code:
    void Human::setAge(int age)
    {
        if (age >= 0) itsAge = age;
        else {
            std::cout << "Negative value passed. Age set to zero." << std::endl;
            itsAge = 0;
        }
    }

  9. #24
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    maxorator, I have given you the right answer. A bool is wrong because it is conceptually wrong. Gender is not a boolean property! Not everything that has only two possible values is a bool.

    Contrary to your belief, bool does not use only one bit. It uses at the very least one byte (nothing can use less than one byte, except bitfields), and sometimes more: early versions of GCC used 4 bytes for bool. And of course, all that is ignoring padding and CPU access speed.

    An enum is the right choice. It enumerates the possible values: male and female. It does not necessarily need more space than a bool either: the compiler can choose how much space it allocates. For a two-value enum, it can allocate a byte, or four bytes, depending on what it thinks is better. Which might depend on the platform, and thus inevitably, in the big picture, is a better choice than what you can make.

    As for #defining identifiers to true and false to give the impression that they're not true and false, that's an atrocity I never want to see again. First, at least use proper C++ constants. Second, if you're redefining the names anyway, why not use an enum? Basically, by doing the redefining, you have just admitted that bool is the wrong choice. And you still don't have one important advantage of enums: the association of the function signatures and variable types with the possible values. With an enum 'Gender' as the type of the variable, you immediately know that you must check the 'Gender' enum for the possible values. With a bool variable, you're left wondering again which value means what. You might discover the #defines, but how can you be sure they're really meant for this usage? Perhaps a different place defines them the other way round, and you're supposed to use those.
    Or consider the resulting documentation. It might say something like this:
    void setGender(bool g);

    Sets the gender of the human. Pass FEMALE for female or MALE for male.
    And every programmer reading it will be like, "What the hell? Since when are MALE and FEMALE boolean values? That should be an enum.


    In conclusion, bool is the wrong type on every, and I mean absolutely every, level. Use bool for real true-false properties, and nothing else.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #25
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    BOOL=2 options=GENDER
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  11. #26
    The larch
    Join Date
    May 2006
    Posts
    3,573
    bool = 2 options = true or false != gender

    Logically bool would only make sense, if gender actually meant isMan (or isWoman). Then you could have a cool class like that:

    Code:
    class Human
    {
        private: 
            bool isMan;
        public: 
            void MakeHumanToMan(bool a)
            {
                isMan = a;
            }
            void MakeHumanToWoman(bool a)
            {
                isMan = !a;
            }
            bool isMan() 
            {
                return isMan;
            }
            bool isWoman()
            {
                return !isMan;
            }
    };
    Last edited by anon; 10-08-2006 at 07:16 AM.

  12. #27
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Ok. I'll build a compiler that also has female and male like it has true and false. The data type will be called gender. Satisfied?
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  13. #28
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No. Current compilers can already do that. That's what enum is for.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #29
    Registered User Queatrix's Avatar
    Join Date
    Apr 2005
    Posts
    1,342
    Quote Originally Posted by maxorator
    #define MALE false
    #define FEMALE true
    No, thats not right, it's more like:
    Code:
    #define MALE true
    #define FEMALE false

  15. #30
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    I made a compromise
    I defined MALE first and FEMALE as true.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Creating a database
    By Shamino in forum Game Programming
    Replies: 19
    Last Post: 06-10-2007, 01:09 PM
  3. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM