How do I overload two different I/O operator in C++ -
i have class this:
myclass { public: int a; unsigned char b,c,d; size_t e,f; double g, h; friend ostream& operator<< (ostream& os, const myclass& mc) { os<<mc.a<<mc.b<<mc.c<<mc.d<<mc.e<<mc.f<<mc.g<<mc.h; return os; } };
i have overloaded <<
operator, want <<
case, how can overloaded 2 different <<
operator?
i thought this:
myclass { public: int a; unsigned char b,c,d; size_t e,f; double g, h; friend ostream& operator<< (ostream& os, const myclass& mc, int type) { if(type==1){ os<<mc.a<<mc.b<<mc.c<<mc.d<<mc.e<<mc.f<<mc.g<<mc.h; return os; } else if(type==2){ os<<mc.a<<mc.c<<mc.d<<mc.e<<mc.g; return os; } };
but didn't work, too many arguments operator function
.
how do?
i have modified class , decided keep original answer reference. version little more elegant in design; cleaner if using error handler / logger library, include them answer large of scale fit here, main function set in try catch block, , error handler , logger work throw errors , quit program if errors critical, or log messages either console window or file if values invalid operation of program still within acceptable state continue.
this class little bloated error messages wouldn't need there, used demonstration show proper program logic flow.
here updated class , main function stated user1024
addresses problem of bool flag variable being set based on fields value instead of function called. can have default values not initialized class, , initialize class same default values. state of class based on function calls , not member values.
temp.h
#ifndef temp_h #define temp_h class temp { friend std::ostream& operator<<(std::ostream& os, const temp& t); private: int m_a, m_b, m_c; double m_d, m_e, m_f; bool m_isinitialized; bool m_updated; const std::string m_strinitmessage = std::string( "first stage values must initalized before calling funciton.\n" ); const std::string m_strupdatemessage = std::string( "setupdatestage needs called first before modifying value.\n" ); public: temp(); temp( int a, int b, int c ); temp( int a, int b, int c, double d, double e, double f ); void setinitialstage( int a, int b, int c ); void setupdatestage( double d, double e, double f ); bool isinitialized() const; bool isupdated() const; int geta() const; int getb() const; int getc() const; // these updating functions not setting functions setinitialstage must called first void updatea( int ); void updateb( int b ); void updatec( int c ); double getd() const; double gete() const; double getf() const; // these updating functions not setting functions both setinitialstage & setupdatestage must called first void updated( double d ); void updatee( double e ); void updatef( double f ); private: // helper function bool teststages(); }; // temp #endif // temp_h
temp.cpp
#include "stdafx.h" #include "temp.h" std::ostream& operator<<( std::ostream& os, const temp& t ) { if ( t.isupdated() ) { os << t.geta() << " " << t.getb() << " " << t.getc() << " " << t.getd() << " " << t.gete() << " " << t.getf() << std::endl; return os; } else { os << t.geta() << " " << t.getb() << " " << t.getc() << std::endl; return os; } } // operator<< temp::temp() : m_a( 0 ), m_b( 0 ), m_c( 0 ), m_d( 0 ), m_e( 0 ), m_f( 0 ), m_isinitialized( false ), m_updated( false ) { } // temp temp::temp( int a, int b, int c ) : m_a( ), m_b( b ), m_c( c ), m_d( 0.0 ), m_e( 0.0 ), m_f( 0.0 ), m_isinitialized( true ), m_updated( false ) { } // temp temp::temp( int a, int b, int c, double d, double e, double f ) : m_a( ), m_b( b ), m_c( c ), m_d( d ), m_e( e ), m_f( f ), m_isinitialized( true ), m_updated( true ) { } // temp void temp::setinitialstage( int a, int b, int c ) { // nothing 2nd stage variables , update flag if ( !m_isinitialized ) { m_a = a; m_b = b; m_c = c; m_isinitialized = true; } else { // not reinitalize std::cout << "initial stage values initialized, please use individual update functions.\n"; return; } } // setinitialstage void temp::setupdatestage( double d, double e, double f ) { // check see if has been intialized first if ( !m_isinitialized ) { std::cout << "\nfirst stage values must initialized first\n"; return; } else { if ( !m_updated ) { // nothing initial values m_d = d; m_e = e; m_f = f; m_updated = true; } else { // not reinitalize std::cout << "update stage values have been initialized, please use individual update functions.\n"; return; } } } // setupdatestage bool temp::isinitialized() const { return m_isinitialized; } // isinitialized bool temp::isupdated() const { return m_updated; } // isupdated int temp::geta() const { if ( !m_isinitialized ) { std::cout << "m_a has not been initialized\n"; return 0; } return m_a; } // geta int temp::getb() const { if (!m_isinitialized) { std::cout << "m_b has not been initialized\n"; return 0; } return m_b; } // getb int temp::getc() const { if ( !m_isinitialized ) { std::cout << "m_c has not been initialized\n"; return 0; } return m_c; } // getc void temp::updatea( int ) { if ( !m_isinitialized ) { std::cout << m_strinitmessage; return; } m_a = a; } // updatea void temp::updateb( int b ) { if ( !m_isinitialized ) { std::cout << m_strinitmessage; return; } m_b = b; } // updateb void temp::updatec( int c ) { if ( !m_isinitialized ) { std::cout << m_strinitmessage; return; } m_c = c; } // updatec double temp::getd() const { if ( !m_updated ) { std::cout << "m_d has not been initialized\n"; return 0; } return m_d; } // getd double temp::gete() const { if (!m_updated) { std::cout << "m_e has not been initialized\n"; return 0; } return m_e; } // gete double temp::getf() const { if (!m_updated) { std::cout << "m_f has not been initialized\n"; return 0; } return m_f; } // getf bool temp::teststages() { if ( !m_isinitialized ) { std::cout << m_strinitmessage; return false; } else { if ( !m_updated ) { std::cout << m_strupdatemessage; return false; } } return true; } // teststages void temp::updated( double d ) { if ( !teststages() ) { return; } m_d = d; } // updated void temp::updatee( double e ) { if ( !teststages() ) { return; } m_e = e; } // updatee void temp::updatef( double f ) { if ( !teststages() ) { return; } m_f = f; } // update
main.cpp
#include "stdafx.h" #include "temp.h" int main() { temp t1; std::cout << "default constructor called." << std::endl; std::cout << t1 << std::endl; // error cases std::cout << "error cases default constructor before setinitialstage called:" << std::endl; std::cout << "---------------------------------------------------------------------" << std::endl; std::cout << "trying update first stage value before setinitialstage called." << std::endl; t1.updatea( 1 ); std::cout << t1 << std::endl; std::cout << "trying update second stage value before setinitialstage called." << std::endl; t1.updated( 2.3 ); std::cout << t1 << std::endl; std::cout << "trying call setupdatestage before m_isinitialized = true" << std::endl; t1.setupdatestage( 4.5, 6.7, 8.9 ); std::cout << t1 << std::endl; // 1st stage initialization wrt using default constructor std::cout << "after setinitalstage called" << std::endl; t1.setinitialstage( 1, 2, 3 ); std::cout << t1 << std::endl; // error cases std::cout << "error cases default constructor after setinitialstage called:" << std::endl; std::cout << "--------------------------------------------------------------------" << std::endl; std::cout << "calling setinitialstage after has been called." << std::endl; t1.setinitialstage( 4, 5, 6 ); std::cout << t1 << std::endl; std::cout << "trying update second stage value after setinitialstage , before setupdatestage have been called." << std::endl; t1.updated( 7.8 ); std::cout << t1 << std::endl; std::cout << "updating first stage value after setinitialstage called." << std::endl; t1.updateb( 9 ); std::cout << t1 << std::endl; std::cout << "calling setupdatedstage." << std::endl; t1.setupdatestage( 10.11, 12.13, 14.15 ); std::cout << t1 << std::endl; // error case std::cout << "error case default constructor after both\n setinitialstage & setupdatestage have been called." << std::endl; std::cout << "------------------------------------------------" << std::endl; std::cout << "calling setupdatestage after has been called." << std::endl; t1.setupdatestage( 16.17, 18.19, 20.21 ); std::cout << t1 << std::endl; std::cout << "updating second stage value afer both setinitializestage & setupdatestage have been called." << std::endl; t1.updatef( 22.23 ); std::cout << t1 << std::endl << std::endl; temp t2( 1, 2, 3 ); std::cout << "first stage constructor called" << std::endl; std::cout << t2 << std::endl; // error cases std::cout << "error cases 1st stage constructor" << std::endl; std::cout << "-------------------------------------" << std::endl; std::cout << "calling setinitialstage after using constructor." << std::endl; t2.setinitialstage( 4, 5, 6 ); std::cout << t2 << std::endl; std::cout << "trying update second stage value before setupdatestage called." << std::endl; t2.updated( 7.8 ); std::cout << t2 << std::endl; std::cout << "updating 1st stage value" << std::endl; t2.updateb( 9 ); std::cout << t2 << std::endl; std::cout << "calling setupdatestage" << std::endl; t2.setupdatestage( 10.11, 12.13, 14.15 ); std::cout << t2 << std::endl; // error case std::cout << "error case 1st stage constructor after setupdatestage has been called." << std::endl; std::cout << "-------------------------------------------------------------------------" << std::endl; t2.setupdatestage( 16.17, 18.19, 20.21 ); std::cout << t2 << std::endl; std::cout << "updating 2nd stage value." << std::endl; t2.updatee( 22.23 ); std::cout << t2 << std::endl << std::endl; temp t3( 1, 2, 3, 4.5, 6.7, 8.9 ); std::cout << "full stage constructor called" << std::endl; std::cout << t3 << std::endl; // error cases std::cout << "error cases full stage constructor:" << std::endl; std::cout << "---------------------------------------" << std::endl; std::cout << "calling setinitialstage" << std::endl; t3.setinitialstage( 10, 11, 12 ); std::cout << t3 << std::endl; std::cout << "calling setupdatestage" << std::endl; t3.setupdatestage( 13.14, 15.16, 17.18 ); std::cout << t3 << std::endl; std::cout << "updating 1st & 2nd stage values" << std::endl; t3.updatea( 19 ); t3.updated( 20.21 ); std::cout << t3 << std::endl; std::cout << "with design 0 acceptable value." << std::endl; std::cout << "updating of t3's values." << std::endl; t3.updatea( 0 ); t3.updateb( 0 ); t3.updatec( 0 ); t3.updated( 0 ); t3.updatee( 0 ); t3.updatef( 0 ); std::cout << t3 << std::endl; std::cout << "using default constructor show both stagefunctions can accept 0 value" << std::endl; temp t4; std::cout << "unitialized:" << std::endl << t4 << std::endl; std::cout << "calling setinitialstage" << std::endl; t4.setinitialstage( 0, 0, 0 ); std::cout << t4 << std::endl; std::cout << "calling setupdatestage" << std::endl; t4.setupdatestage( 0, 0, 0 ); std::cout << t4 << std::endl; std::cout << std::endl; // used break point before application end return 0; } // main
with class having 3 constructors, can create class in 3 ways: creating empty uninitialized version fill out parts later, have 1st stage set upon construction update 2nd stage later, , set stages upon construction. , demonstrates 3 constructors, initializing functions, updating functions , getters working through same std::ostream << operator
. demonstrates how specific functions need called in specific order , demonstrates when not call specific function duplicate times. sure there many other approaches this, being able see same task done in several successful ways has advantages.
Comments
Post a Comment