如何在C ++中重载两个不同的I / O运算符

user1024

我有一个这样的课:

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++运算符I / O重载

来自分类Dev

如何在两个不同的类之间重载“==”运算符?

来自分类Dev

如何区分这两个运算符的重载?

来自分类Dev

如何在C ++中重载赋值运算符

来自分类Dev

如何在C ++中重载索引运算符?

来自分类Dev

如何在C ++中重载赋值运算符

来自分类Dev

如何在 C++ 中重载 ofstream 运算符?

来自分类Dev

用于具有不同数据类型的两个对象的 C++ 重载 + 运算符

来自分类Dev

C ++运算符重载++

来自分类Dev

C ++-重载[]运算符

来自分类Dev

C ++运算符重载

来自分类Dev

C ++“ *”运算符重载

来自分类Dev

C ++运算符>>重载

来自分类Dev

()运算符重载c ++

来自分类Dev

C ++运算符重载[]

来自分类Dev

C ++运算符重载?

来自分类Dev

C ++运算符重载

来自分类Dev

为什么运算符重载实现中的两个静态对象在c ++中始终相等?

来自分类Dev

如何在C ++中正确重载“ <<”运算符?

来自分类Dev

如何在C ++中选择哪个运算符重载?

来自分类Dev

如何在ES6中的两个扩展运算符之间设置逻辑运算符

来自分类Dev

C ++:赋值运算符后的++运算符重载

来自分类Dev

如何重载“==”运算符以确定两个 ID 号是否相同?

来自分类Dev

如何重载in中的运算符?

来自分类Dev

C ++:如何正确重载<运算符?

来自分类Dev

C中的赋值运算符重载

来自分类Dev

<< C ++中的运算符重载错误

来自分类Dev

运算符* = C ++中的重载

来自分类Dev

C ++中的重载运算符<