我有一个这样的课:
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;
}
};
我已经重载了<<
运算符,但是我还想要另一种<<
情况,如何重载两个不同的<<
运算符?
我是这样想的:
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;
}
};
但是没有用Too many arguments for this operator function
。
我该怎么办?
我已经修改了该类,并决定保留原始答案以供参考。现在,此版本的设计更加优雅。但是,如果我使用错误处理程序/记录器库,可能会更清洁,但是要在此答案中包含它们,是为了适应此处的规模,但主要功能将设置在try catch块中,而我的错误如果错误很严重,处理程序和记录器将抛出错误并退出程序,或者如果值无效但程序的操作仍处于可接受的状态下继续操作,则将消息记录到控制台窗口或文件中。
该类有点error肿,但通常不会在该处出现错误消息,但将其用作演示以显示适当的程序逻辑流程。
这是我说过的更新后的类和主要函数,user1024
用于解决基于字段值而不是调用哪个函数来设置bool标志变量的问题。现在,他可以拥有未初始化为该类的默认值,然后使用相同的默认值初始化该类。现在,类的状态基于函数调用而不是成员值。
温度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 be initalized before calling this funciton.\n" );
const std::string m_strUpdateMessage = std::string( "setUpdateStage needs to be called first before modifying this 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 Are Updating Functions Not Setting Functions setInitialStage Must Be Called First
void updateA( int a );
void updateB( int b );
void updateC( int c );
double getD() const;
double getE() const;
double getF() const;
// These Are Updating Functions Not Setting Functions Both setInitialStage & setUpdateStage Must Be Called First
void updateD( double d );
void updateE( double e );
void updateF( double f );
private:
// Helper Function
bool testStages();
}; // Temp
#endif // TEMP_H
温度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( 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( 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 ) {
// Do Nothing With 2nd Stage Variables And Update Flag
if ( !m_isInitialized ) {
m_a = a;
m_b = b;
m_c = c;
m_isInitialized = true;
} else {
// Do not Reinitalize
std::cout << "Initial stage values are already initialized, please use the individual update functions.\n";
return;
}
} // setInitialStage
void Temp::setUpdateStage( double d, double e, double f ) {
// Check To See If This Has Been Intialized First
if ( !m_isInitialized ) {
std::cout << "\nFirst Stage values must be initialized first\n";
return;
} else {
if ( !m_updated ) {
// Do nothing with Initial Values
m_d = d;
m_e = e;
m_f = f;
m_updated = true;
} else {
// Do Not Reinitalize
std::cout << "Update stage values have already been initialized, please use the 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 a ) {
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 For Default Constructor Before setInitialStage is called:" << std::endl;
std::cout << "---------------------------------------------------------------------" << std::endl;
std::cout << "Trying to update a first stage value before setInitialStage is called." << std::endl;
t1.updateA( 1 );
std::cout << t1 << std::endl;
std::cout << "Trying to update a second stage value before setInitialStage is called." << std::endl;
t1.updateD( 2.3 );
std::cout << t1 << std::endl;
std::cout << "Trying to 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 To Using A Default Constructor
std::cout << "After setInitalStage is called" << std::endl;
t1.setInitialStage( 1, 2, 3 );
std::cout << t1 << std::endl;
// Error Cases
std::cout << "Error Cases For Default Constructor After setInitialStage is called:" << std::endl;
std::cout << "--------------------------------------------------------------------" << std::endl;
std::cout << "Calling setInitialStage after it has already been called." << std::endl;
t1.setInitialStage( 4, 5, 6 );
std::cout << t1 << std::endl;
std::cout << "Trying to update a second stage value after setInitialStage and before setUpdateStage have been called." << std::endl;
t1.updateD( 7.8 );
std::cout << t1 << std::endl;
std::cout << "Updating a first stage value after setInitialStage is 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 For Default Constructor After Both\n setInitialStage & setUpdateStage have been called." << std::endl;
std::cout << "------------------------------------------------" << std::endl;
std::cout << "Calling setUpdateStage after it has already 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 For 1st Stage Constructor" << std::endl;
std::cout << "-------------------------------------" << std::endl;
std::cout << "Calling setInitialStage after using this constructor." << std::endl;
t2.setInitialStage( 4, 5, 6 );
std::cout << t2 << std::endl;
std::cout << "Trying To Update Second Stage Value Before setUpdateStage is 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 For 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 For 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 this design 0 is now an acceptable value." << std::endl;
std::cout << "Updating all 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 To Show That Both stageFunctions Can accept 0 as 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 As A Break Point Before Application End
return 0;
} // main
使用具有3个构造函数的此类,您可以通过3种方式创建该类:创建一个空的未初始化版本以稍后填充所有零件,在构建时设置第一阶段以在以后更新第二阶段,最后在之后完全设置所有阶段建造。并且这也证明了所有3个构造函数,所有初始化函数,更新函数和getter都通过相同的方法工作std::ostream << operator
。它还演示了如何需要按特定顺序调用特定函数,并演示了何时不重复调用特定函数。我相信还有很多其他方法,但是能够以几种成功的方式完成相同的任务有其优势。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句