//设计一个动态流,可以实时动态切换文本输出流向。
//顶层类是一个抽象类Printer,并且提供一个纯虚函数;输出字符串。
//由Shape类派生PrintFilter(信息过滤)、Print2UI(UI显示)和Print2File(文本存储)
//在主函数测试中使用多态方式调用不同对象的输出函数。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

//创建一个抽象类
class Printer
{
public:
    virtual ~Printer(){}
    virtual void showInfo(const string&) = 0;  //显示输出文本
};

// 文本过滤器
class PrintFilter : public Printer
{
public:
    Printer& out;
    PrintFilter(Printer& n) :out(n){ }
    virtual void showInfo(const string& n)
    {
        string tmp(n);
        tmp += "(filter)";
        out.showInfo(tmp);
    }
};

// 控制台输出流
class Print2UI :public Printer
{
public:
    virtual void showInfo(const string& n)
    {
        cout << n;
    }
};

// 文本输出
class Print2File : public Printer
{
public:
    ofstream file;// 文本流
    Print2File(const string& n){ file.open(n); }// 打开文本
    ~Print2File(){ file.close(); }// 关闭文本

public:
    virtual void showInfo(const string& n) { 
        file << n;
    }
};

//打印输出
void printInfo(Printer& emp)
{
    // 这里使用的就是多态性来调用的函数
    emp.showInfo("message1\n");
    emp.showInfo("message2\n");
}

int main(void)
{
    Print2File     t1("out.txt");
    Print2UI       s1;
    PrintFilter    sm1(s1);

    printInfo(t1);
    printInfo(s1);
    printInfo(sm1);

    // 暂停
    system("pause");
    return EXIT_SUCCESS;
}