类输出控制实现

来源:互联网 发布:access数据库设计实例 编辑:程序博客网 时间:2024/06/10 17:53

通过下列步骤将一个类的输出控制交由OutputCtrlProxy托管:

    在类头文件包含output_ctrl

    声明中包含宏OUTPUT_CTRL_DECLARE

    定义前包含宏OUTPUT_CTRL_DEFINE(className)

    增加虚函数void className::Output()const定义

 

支持的控制

   className::SetOutputFlag(OUTPUT_NONE);
    不输出

    className::SetOutputFlag(OUTPUT_PRINT);
     打印

    className::SetOutputFlag(OUTPUT_WRITE,OUTPUT_PATH);
    写到指定文件

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

output_ctrl.h

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#ifndef _OUTPUT_CTRL_
#define _OUTPUT_CTRL_

#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;

#include "basic_type.h"

#define MAX_CTRL_ENTITY 128

typedef  int CtrlId;

typedef enum
{
    OUTPUT_NONE,
    OUTPUT_PRINT,
    OUTPUT_WRITE,
}OutputFlag;

class OutputCtrlProxy
{
public:
    static OutputCtrlProxy *Instance();
 void SetAllFlag(OutputFlag val);
   
    CtrlId     GetCtrlId();
    void       SetOutputFlag(CtrlId id,OutputFlag val,const char *outputPath=NULL);
    void       Act(CtrlId id,const char *fmt, ...);
    OutputFlag ActFlag(CtrlId id);
protected:
 OutputCtrlProxy();
private:
    static OutputCtrlProxy *_instance;
    ofstream               *_outputFile;

    int        _entityNum;
    OutputFlag _flags[MAX_CTRL_ENTITY];
};

/*****************************************************
        USER MACRO
*****************************************************/
#define OUTPUT_CTRL_DECLARE \
virtual void Output()const; \
static void  SetOutputFlag(OutputFlag val,const char *outputPath=NULL); \
static int   GetCtrlId(); \
static int   _ctrlId;

#define OUTPUT_CTRL_DEFINE(className) \
int className::_ctrlId = 0; \
int className::GetCtrlId() \
{ \
    if(_ctrlId==0) \
    { \
        OutputCtrlProxy *p = OutputCtrlProxy::Instance(); \
        _ctrlId = p->GetCtrlId(); \
    } \
    return _ctrlId; \
} \
\
void className::SetOutputFlag(OutputFlag val,const char *outputPath) \
{ \
    OutputCtrlProxy *p = OutputCtrlProxy::Instance(); \
    p->SetOutputFlag(GetCtrlId(),val,outputPath); \
}

#endif

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

output_ctrl.cpp

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <stdarg.h>

#include "output_ctrl.h"

OutputCtrlProxy *OutputCtrlProxy::_instance = NULL;

OutputCtrlProxy *OutputCtrlProxy::Instance()
{
    if(_instance==0)
    {
        _instance = new OutputCtrlProxy;
    }
    return _instance;
}

CtrlId OutputCtrlProxy::GetCtrlId()
{
    return ++_entityNum;
}

void OutputCtrlProxy::SetOutputFlag(CtrlId id,OutputFlag val,const char *path)
{
    _flags[id-1] = val;
    if( val==OUTPUT_WRITE && _outputFile==NULL )
    {
        if(path!=NULL)
        {
            _outputFile = new ofstream(path);
        }
    }
}

void OutputCtrlProxy::Act(CtrlId id,const char *fmt, ...)
{
    if( _flags[id-1]!=NULL )
    {
        char tmpBuffer[1024] = {0};
        va_list argptr;
        memset(&argptr, 0, sizeof(va_list));
        va_start (argptr, fmt);
        vsprintf(tmpBuffer, fmt, argptr);
        va_end (argptr);

        if( _flags[id-1]==OUTPUT_PRINT )
        {
            printf("%s", tmpBuffer);
        }
        else if( _flags[id-1]==OUTPUT_WRITE )
        {
            if(_outputFile!=NULL)
            {
                _outputFile->write(tmpBuffer,strlen(tmpBuffer));
            }
        }
    }
}

OutputFlag OutputCtrlProxy::ActFlag(CtrlId id)
{
    return _flags[id-1];
}

OutputCtrlProxy::OutputCtrlProxy()
{
    for(int i=0;i<MAX_CTRL_ENTITY;i++)
    {
         _flags[i] = OUTPUT_NONE;
    }
    _entityNum  = 0;
    _outputFile = NULL;
}

void OutputCtrlProxy::SetAllFlag(OutputFlag val)
{
    for(int i=0;i<_entityNum;i++)
    {
        _flags[i] = OUTPUT_PRINT;
    }
    _entityNum = 0;
}

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

test_output_ctrl.cpp

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "token.h"
#include "TokenDerive.h"
#include "PrecompileBuilder.h"

#define OUTPUT_PATH "E:\\code_analyze\\code\\test_data\\test_output\\output.txt"

class Entity1
{
public:
    OUTPUT_CTRL_DECLARE

    void Output();
    void Output(int printId);
};

OUTPUT_CTRL_DEFINE(Entity1)

void Entity1::Output()const
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId,"Entity1 output action\n");
}

void Entity1::Output()
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId,"Entity1 output action\n");
}

void Entity1::Output(int id)
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId," %d -%s",id,"Entity1 output action\n");
}

class Entity2
{
public:
    OUTPUT_CTRL_DECLARE
       
    void Output();
    void Output(int printId);
};

OUTPUT_CTRL_DEFINE(Entity2)

void Entity2::Output()const
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId,"Entity1 output action\n");
}

void Entity2::Output()
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId,"Entity2 output action\n");
}

void Entity2::Output(int id)
{
    OutputCtrlProxy *p = OutputCtrlProxy::Instance();
    p->Act(_ctrlId," %d -%s",id,"Entity2 output action\n");
}

void test_ctrl_id()
{
    Entity1 e1_1;
    Entity1 e1_2;
    assert( e1_2.GetCtrlId()==e1_1.GetCtrlId() );
    Entity2 e2_1;
    Entity2 e2_2;
    assert( e2_1.GetCtrlId()==e2_1.GetCtrlId() );
    Entity1 e1_3;
    assert( e1_3.GetCtrlId()==e1_1.GetCtrlId() );
    Entity2 e2_3;
    assert( e2_3.GetCtrlId()==e2_1.GetCtrlId() );
}

void test_simple_print()
{
    printf("show entity1,don't show entity2\n");
    Entity1::SetOutputFlag(OUTPUT_PRINT);
    Entity2::SetOutputFlag(OUTPUT_NONE);
    Entity1 e1_1,e1_2;
    e1_1.Output();
    e1_2.Output();
    Entity2 e2_1,e2_2;
    e2_1.Output();
    e2_2.Output();

    printf("show entity2,don't show entity1\n");
    Entity1::SetOutputFlag(OUTPUT_NONE);
    Entity2::SetOutputFlag(OUTPUT_PRINT);
    e1_1.Output();
    e1_2.Output();
    e2_1.Output();
    e2_2.Output();
}

void test_complicate_print()
{
    int printId = 0;
    printf("show entity1,don't show entity2\n");
    Entity1::SetOutputFlag(OUTPUT_PRINT);
    Entity2::SetOutputFlag(OUTPUT_NONE);
    Entity1 e1_1,e1_2;
    e1_1.Output(printId++);
    e1_2.Output(printId++);
    Entity2 e2_1,e2_2;
    e2_1.Output(printId++);
    e2_2.Output(printId++);

    printf("show entity2,don't show entity1\n");
    Entity1::SetOutputFlag(OUTPUT_NONE);
    Entity2::SetOutputFlag(OUTPUT_PRINT);
    e1_1.Output(printId++);
    e1_2.Output(printId++);
    e2_1.Output(printId++);
    e2_2.Output(printId++);
}

void test_print()
{
    test_ctrl_id();
    test_simple_print();
    test_complicate_print();
}

void test_write()
{
    int     printId = 0;
    Entity1 e1_1;
    Entity2 e2_1;
   
    Entity1::SetOutputFlag(OUTPUT_PRINT);
    e1_1.Output(printId++);
    Entity1::SetOutputFlag(OUTPUT_WRITE,OUTPUT_PATH);
    e1_1.Output(printId++);
    Entity2::SetOutputFlag(OUTPUT_WRITE,OUTPUT_PATH);
    e2_1.Output(printId++);
}

void test_output_ctrl()
{
    printf("=======test_output_ctrl print=========\n");
    test_print();
    printf("=======test_output_ctrl write file====\n");
 test_write();
}

 

原创粉丝点击