Thread: operator '>>' reuse

  1. #31
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Actually, you know, the reason they asked you two to have two functions is to avoid ambiguity. So that anyone reading the code would understand what function does what.
    Therefore, I will suggest you either use two functions for reading and no operator >> or make two classes, one for files, one for console input, both with operator >> or appropriate Read function.
    Or again, as I suggested, one class and one operator >> and make sure that all the dates and format LOOK THE SAME. IF the layout is the same, then it does not matter whether it reads from file or console.

    And never put prompts into operator >>. Ever. That destroys the concept of a class.
    Instead put prompts outside the operator >> to the supposed caller of the function. It should fill out an appropriate object and then serialize that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #32
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    Actually, you know, the reason they asked you two to have two functions is to avoid ambiguity. So that anyone reading the code would understand what function does what.
    Therefore, I will suggest you either use two functions for reading and no operator >> or make two classes, one for files, one for console input, both with operator >> or appropriate Read function.
    Or again, as I suggested, one class and one operator >> and make sure that all the dates and format LOOK THE SAME. IF the layout is the same, then it does not matter whether it reads from file or console.

    And never put prompts into operator >>. Ever. That destroys the concept of a class.
    Instead put prompts outside the operator >> to the supposed caller of the function. It should fill out an appropriate object and then serialize that.
    Who should i listen to

  3. #33
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    BTW, if i were to prompt outside the '>>' function, how is it possible to 1. PROMPT 2. READ 3. PROMPT 4. READ, since all the 'reads' are done inside the '>>' ?

    also,

    Therefore, I will suggest you either use two functions for reading and no operator >>
    This was my initial thought when i started this program, but some1 suggested to overload stream operators to accept inputs... I think that some1 was you if am not mistaken !!! And i found that quite cool and better

    Lastly, A class to JUST read input, mhhh ! Interesting

  4. #34
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    and make sure that all the dates and format LOOK THE SAME. IF the layout is the same, then it does not matter whether it reads from file or console.
    If i'm going to need to prompt for command inputs, unfortunately the format will never look the same. And, i'm never reading dates from the user. The only time i read dates is from file

  5. #35
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by csonx_p View Post
    BTW, if i were to prompt outside the '>>' function, how is it possible to 1. PROMPT 2. READ 3. PROMPT 4. READ, since all the 'reads' are done inside the '>>' ?
    What you've essentially done is put a free function as an >> operator. That's wrong. The code should be a free function since it has nothing to do with the object itself.

    also,
    This was my initial thought when i started this program, but some1 suggested to overload stream operators to accept inputs... I think that some1 was you if am not mistaken !!! And i found that quite cool and better
    Yes, but it seems you misunderstand.
    In order what I suggested:

    1) TWO classes with one operator >> each.
    2) ONE class and NO operator >> (instead two functions).

    If I saw one class and one operator >> and one Read function, I might become confused. This is what others have suggested. That you simply use two member functions.

    Quote Originally Posted by csonx_p View Post
    If i'm going to need to prompt for command inputs, unfortunately the format will never look the same. And, i'm never reading dates from the user. The only time i read dates is from file
    I really fail to understand what it is you need to separate read functions for, if there's only one thing you read.
    But if the files date formats are different, then you can make sure they are THE SAME, and you can get away with only one operator >>. That's what I've been suggesting as an alternative.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #36
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    What you've essentially done is put a free function as an >> operator. That's wrong. The code should be a free function since it has nothing to do with the object itself.


    Yes, but it seems you misunderstand.
    In order what I suggested:

    1) TWO classes with one operator >> each.
    2) ONE class and NO operator >> (instead two functions).

    If I saw one class and one operator >> and one Read function, I might become confused. This is what others have suggested. That you simply use two member functions.


    I really fail to understand what it is you need to separate read functions for, if there's only one thing you read.
    But if the files date formats are different, then you can make sure they are THE SAME, and you can get away with only one operator >>. That's what I've been suggesting as an alternative.
    Let me admit, i'm getting confused now ... Maybe examples will help!!!!

  7. #37
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    1) TWO classes with one operator >> each.
    1. What do you mean by TOW classes anyway ... Take for example class Contract. It will display its contract details (or member data) .. So, how does 'TWO' classes come in here?

    2. So you suggestion that this code is fine without even worrying about coding overloaded '>>', unless if the compiler complains ...

  8. #38
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, the most basic component. It's the dates you have problems reading, no?
    Then there should be a date class. The date class can handle reading dates.
    And if there are different dates from different files, then you might have two date classes: CDateFile, CDateSpecialFile or whatever. That's what I mean.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #39
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    >> No, the most basic component. It's the dates you have problems reading, no?

    He seems to be reading dates just fine. It's when he's supposed to read them that is the problem. Depending on how it's used the contract's signing date and other important times is determined by the clock. Parsing and so forth is the simple part which he happens to have controlled by a date class.

    With that reasoning, I still think the two read functions are the simplest solution. It doesn't make sense for contract to have an operator>>.

    I did it like this using the ctime library:
    Code:
    //needTime
    //Convert a formatted time string to time_t data.
    //mytime [in] - must be in dd/mm/yyyy format
    std::time_t Contract::needTime (const std::string & mytime)
    {
        std::tm breakdown = { 0, };
        std::stringstream timebuf(mytime);
    
        timebuf >> breakdown.tm_mday;
        if (timebuf.peek() == '/')
            timebuf.ignore();
        else 
            return std::time_t(-1);
    
        timebuf >> breakdown.tm_mon;
        if (timebuf.peek() == '/')
            timebuf.ignore();
        else
            return std::time_t(-1);
    
        timebuf >> breakdown.tm_year;
        breakdown.tm_year -= 1900;
    
        return std::mktime(&breakdown);
    }
    
    //needTime
    //Returs the time according to the local user clock.
    std::time_t Contract::needTime ()
    {
        return std::time(0);
    }
    
    //read
    //User-entered contract.
    //Returns zero on success.
    bool Contract::read()
    {
        std::time_t new_date;
        new_date = needTime();
        if (new_date == time_t(-1)) {
            return true;
        }
        else {
            date_of_signing = new_date;
            return false;
        }
    }
    
    //read
    //Get a date (and the rest of the contract) from a file.
    //indata [in] - The file stream to read.
    //Returns zero on success.
    bool Contract::read (std::ifstream & indata)
    {
        std::string some_date;
        std::time_t new_date;
    
        std::getline(indata, some_date);
        new_date = needTime(some_date);
    
        if (new_date == time_t(-1)) {
            return true;
        }
        else {
            date_of_signing = new_date;
            return false;
        }
    }
    Last edited by whiteflags; 08-28-2008 at 09:35 PM.

  10. #40
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    It doesn't make sense for contract to have an operator>>.
    It makes perfect sense. (I'm thinking of bulk input here as when one might migrate from software to software.) What doesn't make sense is associating prompting and unreliable input with a serialization function. If his 'operator >>' required the input to be well-formed this wouldn't have been a problem.

    Serialization is arguably a part of an object's job description. Transforming input from one format to another is not an object's job unless the object exist solely to facility such transformations.

    The object here should probably know how to serialize itself, and having the object serialize to and from a "dumb string" is fine, but generating this well-formed "dumb string" from unreliable input shouldn't be a part of the object. This simple approach gives a great many benefits.

    Consider the opportunities provided here:
    there is no confusion about what 'operator >>' does.
    there is no confusion between various 'read' methods.
    one may develop their own functions handling other forms of unreliable data.
    the program has better support for pipes.

    Soma

  11. #41
    Registered User
    Join Date
    Jan 2008
    Posts
    66
    Maybe this would give you an idea:

    Code:
    #include <string>
    #include <ctime>
    #include <iostream>
    
    int main(int argc, char *argv[])
    {
       time_t t;
       struct tm *area;
    
       t = time(NULL);
       area = localtime(&t);
    
       std::string currenttime = asctime(area);
       
       std::cout << currenttime;
       
       return 0;
    }
    Last edited by ThLstN; 08-29-2008 at 12:47 AM.

  12. #42
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    Current read structure

    Let me explain my read functions with owner classes

    1. The Contract Class

    Code:
    // Read the contract details from file, or enter new contract
    bool Contract::Read(std::istream& indata, bool newContract, std::string refNum)
    {
    	// Read each record
    	indata >> *this;	
    
    	contractID=refNum;
    
    	Date issueDate;
    
    	// Set rental dates to current date
    	if(newContract)	{
    		issueDate.SetDate( issueDate.getCurrentTime() );
    	}
    	else
    		indata >> issueDate;
    
    	return indata.fail();
    }
    
    // Overload for reading contract details from a command screen
    std::istream& operator >> (std::istream& in, Contract& contract)
    {
    	std::string rentalType;
    	std::string carReg;
    	char carGrp;
    
    	system("cls");
    
    	std::cout << "\n     \t\t\t&#201;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#187;\n";
    	std::cout << "     \t\t\t&#186;         CONTRACT DETAILS      &#186;\n";
    	std::cout << "     \t\t\t\314&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;\271\n";
    
    	std::cout << "\n\n\nEnter new contract data below..." << std::endl;
    	in.ignore();
    
    	std::cout << "\n1. Car registration number : ";
    	in >> carReg;
    
    	std::cout << "\n2. Rental group [A/B/C/D/F/O/Z] : ";
    	in >> carGrp;
    
    	std::cout << "\n3. Rental Type [\"Unlimited\" OR \"200km\"]" ;
    	in >> rentalType;
    
    	contract.SetContractDetails(carReg, rentalType, carGrp);
    
    	return in;
    }
    
    // Overload for reading contract details from a filestream
    std::ifstream& operator >> (std::ifstream& in, Contract& contract)
    {
    	std::string contractID;
    	std::string rentalType;
    	std::string carReg;
    	char carGrp;
    
    	in >> contractID;
    	in >> carReg;
    	in >> carGrp;
    	in >> rentalType;
    
    	contract.SetContractDetails(carReg, rentalType, carGrp);
    
    	return in;
    }

    2. Driver Class

    Code:
    // Overload for reading command prompt inputs
    std::istream& operator>>(std::istream& in, Driver& driver)
    {
    	std::string fname, sname, contact;
    	std::string IDNo;
    
    	system("cls");
    	
    	std::cout << "\n     \t\t\t&#201;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#187;\n";
    	std::cout << "     \t\t\t&#186;         DRIVER DETAILS        &#186;\n";
    	std::cout << "     \t\t\t\314&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;\271";
    
    	std::cout << "\n\n\nEnter the following Driver's details\n\n";
    	
    	std::cout << "\nFull Name : "; 
    	in >> fname >> sname;
    
    	std::cout << "\nDriver's ID Number : ";
    	in >> IDNo;
    
    	std::cout << "\nContact Number [ccc-ddd-dddd] : ";
    	in >> contact;
    
    	driver.address.Read(in);
    	
    	driver.SetDriverDetails(fname, sname, IDNo, contact);
    	
    	return in;
    }
    
    // Overload for reading input file streams 
    std::ifstream& operator>>(std::ifstream& in, Driver& driver)
    {
    	std::string fname, sname, licNo, contact;
    	Address add;
    	std::string IDNo;
    
    	in >> fname >> sname;
    	in >> IDNo;
    	in >> contact;
    	in >> add;
    
    	driver.SetDriverDetails(fname, sname, IDNo, contact);
    	
    	return in;
    }
    
    // Read driver's data from input stream
    bool Driver::Read(std::istream& indata, std::string* refNo)
    {
    	indata >> *this;	
    	*refNo = getIDNo();
    
    	return indata.fail();
    }
    3. Date Class

    Code:
    void Date::SetDate(tm curr_tm)
    {
    	day = curr_tm.tm_mday;
    	month = curr_tm.tm_mon;
    	year = curr_tm.tm_year;
    	hour = curr_tm.tm_hour;
    	minute = curr_tm.tm_min;
    	local_dt = curr_tm;
    }
    
    // Overide operator >> to read date
    istream& operator>>(istream& in, Date& date)
    {
    	in >> date.year;
    	in >> date.month;
    	in >> date.day;
    	in >> date.hour;
    	in >> date.minute;
    	
    	return in;
    }
    
    // Get the current system's time
    tm Date::getCurrentTime()
    {
    	time_t rawtime;
    	tm* timeinfo;
    
    	time( &rawtime );
    	timeinfo = localtime ( &rawtime );
    
    	return *timeinfo;
    }
    4. Address Class

    Code:
    // Overload for reading input file streams 
    std::istream& operator>>(std::istream& in, Address& address)
    {
    	std::string fline, sline, sbb, city, cde;
    	
    	system("cls");
    
    	std::cout << "\n     \t\t\t&#201;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#187;\n";
    	std::cout << "     \t\t\t&#186;        PHYSICAL ADDRESS       &#186;\n";
    	std::cout << "     \t\t\t\314&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;\271";
    
    	std::cout << "\n\n\nEnter physical address below ...";
    	
    	std::cout << "\n\n1. FirstLine : ";
    	in >> fline;
    
    	std::cout << "\n2. SecondLine : ";
    	in >> sline;
    
    	std::cout << "\n3. Surbub : "; 
    	in >> sbb;
    
    	std::cout << "\n4. City : ";
    	in >> city;	
    	
    	std::cout << "\n5. Code : "; 
    	in >> cde;
    	
    	address.SetAddress(fline, sline, sbb, city, cde);
    	
    	return in;
    }
    
    // Overload for reading input file streams 
    std::ifstream& operator>>(std::ifstream& in, Address& address)
    {
    	std::string fline, sline, sbb, city, cde;
    	
    	in >> fline;
    	in >> sline;
    	in >> sbb;
    	in >> city;	
    	in >> cde;
    	
    	address.SetAddress(fline, sline, sbb, city, cde);
    	
    	return in;
    }
    
    // Read driver's address from input stream
    bool Address::Read(std::istream& indata)
    {
    	indata >> *this;	
    	return indata.fail();
    }
    5. Now, lets use these whenwe create the contract

    In Rental.cpp we creant NewContract

    Code:
    // Add new user contract to the list
    void Rental::CreateNewContract()
    {
    	std::string referenceNo;
    
    	// Read driver's details
    	driver.Read(cin, &referenceNo);	
    	
    	// Read contract details
    	Contract contract;	
    	contract.Read(cin, true, referenceNo);	
    	
    	contracts.push_back(contract);
    
    	puts("\ncontract added...\n");		
    }
    Hope you have a better picture of what am trying to do ... Your views and comments are welcomed as usual

  13. #43
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by csonx_p View Post
    Let me explain my read functions with owner classes

    1. The Contract Class

    Code:
    // Read the contract details from file, or enter new contract
    bool Contract::Read(std::istream& indata, bool newContract, std::string refNum)
    {
    	// Read each record
    	indata >> *this;	
    
    	contractID=refNum;
    
            //Date issueDate;
    
    	// Set rental dates to current date
    	if(newContract)	{
    		issued.SetDate( issued.getCurrentTime() );
    	}
    	else
    		indata >> issued;
    
    	return indata.fail();
    }
    Made a mistake here, note the changes in red. Issued is member of contract

  14. #44
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    std::istream& operator>>(std::istream& in, Address& address)
    {
    	std::string fline, sline, sbb, city, cde;
    	
    	system("cls");
    
    	std::cout << "\n     \t\t\t浜様様様様様様様様様様様様様様様\n";
    	std::cout << "     \t\t\t        PHYSICAL ADDRESS       \n";
    	std::cout << "     \t\t\t\314様様様様様様様様様様様様様様様\271";
    
    	std::cout << "\n\n\nEnter physical address below ...";
    	
    	std::cout << "\n\n1. FirstLine : ";
    	in >> fline;
    
    	std::cout << "\n2. SecondLine : ";
    	in >> sline;
    
    	std::cout << "\n3. Surbub : "; 
    	in >> sbb;
    
    	std::cout << "\n4. City : ";
    	in >> city;	
    	
    	std::cout << "\n5. Code : "; 
    	in >> cde;
    	
    	address.SetAddress(fline, sline, sbb, city, cde);
    	
    	return in;
    }
    This is not a proper operator>> - it should be a function.

    And I think this
    Code:
    	std::cout << "\n3. Surbub : ";
    should be
    Code:
    	std::cout << "\n3. Town : ";
    [or possibly "Suburb"/"District" (or just "Third line").

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #45
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Same goes for the address class.
    Heck, I'd get a heart attack if my contract suddenly started asking "please give me your physical address." We're talking about a contract here! It's deaf; it's stupid and it can't talk! It's inanimate.
    YOU who hold it is the one who must fill it out with information, NOT the contract itself (is this some kind of new smart contract???).

    And essentially, your Read function is pretty much the operator >> instead.
    And you also seem to have missed the point again. You are basically creating a Read function and then an operator >>. They are supposed to do the same thing here! Operator >> reads.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. what design patter let me reuse this class?
    By patiobarbecue in forum C++ Programming
    Replies: 4
    Last Post: 04-29-2009, 01:44 PM
  2. reuse a socket connection
    By radeberger in forum Networking/Device Communication
    Replies: 0
    Last Post: 03-18-2009, 11:38 AM
  3. Deallocate Memory and reuse pointer
    By appleGuy in forum C++ Programming
    Replies: 9
    Last Post: 06-20-2007, 11:07 AM
  4. homework v.s. reuse
    By xddxogm3 in forum C++ Programming
    Replies: 2
    Last Post: 12-08-2003, 02:18 PM
  5. exceptions: reuse <stdexcept> classes???
    By Ruchikar in forum C++ Programming
    Replies: 5
    Last Post: 06-25-2002, 03:09 AM