C++ C++;缩进输出类继承流

C++ C++;缩进输出类继承流,c++,c++11,std,ofstream,manipulators,C++,C++11,Std,Ofstream,Manipulators,所以我想写一个缩进输出类,可以这样使用: Debug f; f.open("test.txt"); f << Debug::IndS << "Start" << std::endl; f << Debug::Ind << "test" << std::endl; f << Debug::IndE << "End" << std::endl; 所以Ind将打印当前缩进和递增缩进,Ind将打

所以我想写一个缩进输出类,可以这样使用:

Debug f;
f.open("test.txt");
f << Debug::IndS << "Start" << std::endl;
f << Debug::Ind << "test" << std::endl;
f << Debug::IndE << "End" << std::endl;
所以Ind将打印当前缩进和递增缩进,Ind将打印当前缩进,Ind将递减缩进并打印当前缩进。我尝试过这样创建它:

class Debug : public std::ofstream {
    public:
        Debug();
        ~Debug();

    private:
        std::string IndentText;
        int _Indent;

    public:
        void SetIndentText(const char* Text);
        inline void Indent(int Amount);
        inline void SetIndent(int Amount);

        inline std::ofstream& Ind (std::ofstream& ofs);
        inline std::ofstream& IndS(std::ofstream& ofs);
        inline std::ofstream& IndE(std::ofstream& ofs);
};

Debug::Debug () : std::ofstream() {
    IndentText = "    ";
}

Debug::~Debug () {
}

void Debug::SetIndentText (const char* Text) {
    IndentText = Text;
}

void Debug::Indent (int Amount) {
    _Indent += Amount;
}

void Debug::SetIndent(int Amount) {
    _Indent = Amount;
}

std::ofstream& Debug::Ind (std::ofstream& ofs) {
    for (int i = 0;i < _Indent;i++) {
        ofs << IndentText;
    }
    return ofs;
}

std::ofstream& Debug::IndS (std::ofstream& ofs) {
    ofs << Ind;
    _Indent++;
    return ofs;
}

std::ofstream& Debug::IndE (std::ofstream& ofs) {
    _Indent--;
    ofs << Ind;
    return ofs;
}
类调试:公共std::of流{ 公众: 调试(); ~Debug(); 私人: std::字符串缩进文本; 整数缩进; 公众: void SetIndentText(常量字符*文本); 内联无效缩进(整数金额); 内联void SetIndent(整数金额); 在线标准:ofstream&Ind(标准:ofstream&ofs); 在线标准:ofstream&IndS(标准:ofstream&ofs); 在线标准:ofstream&IndE(标准:ofstream&ofs); }; Debug::Debug():std::ofstream(){ 缩进文本=”; } 调试::~Debug(){ } void Debug::SetIndentText(常量字符*Text){ 缩进文本=文本; } 无效调试::缩进(整数金额){ _缩进+=金额; } void Debug::SetIndent(整数金额){ _缩进=金额; } std::ofstream&Debug::Ind(std::ofstream&ofs){ 对于(int i=0;i<\u缩进;i++){
ofs您通常不应该继承
std::ostream
或类似于
std::ofstream
的它的实现。请将它们包装到另一个类中

下面是我在评论中提到的想法的简短概述

#include <iostream>
#include <fstream>

using namespace std;

class Logger {
public:
    Logger(ostream& os) : os_(os), curIndentLevel_(0) {}
    void increaseLevel() { ++curIndentLevel_; }
    void decreaseLevel() { --curIndentLevel_; }

private:
    template<typename T> friend ostream& operator<<(Logger&, T);

    ostream& os_;
    int curIndentLevel_;
};

template<typename T> 
ostream& operator<<(Logger& log, T op) {
    for(int i = 0; i < log.curIndentLevel_ * 4; ++i) {
        log.os_ << ' ';
    }
    log.os_ << op;
    return log.os_;
}

int main() {
    Logger log(cout);
    log.increaseLevel();
    log << "Hello World!" << endl;
    log.decreaseLevel();
    log << "Hello World!" << endl;
    return 0;
}



这里有一个小变体,展示了如何使用
操作符简化编码。您通常不应该继承
std::ostream
或它的实现,如
std::ofstream
。将它们包装到另一个类中

下面是我在评论中提到的想法的简短概述

#include <iostream>
#include <fstream>

using namespace std;

class Logger {
public:
    Logger(ostream& os) : os_(os), curIndentLevel_(0) {}
    void increaseLevel() { ++curIndentLevel_; }
    void decreaseLevel() { --curIndentLevel_; }

private:
    template<typename T> friend ostream& operator<<(Logger&, T);

    ostream& os_;
    int curIndentLevel_;
};

template<typename T> 
ostream& operator<<(Logger& log, T op) {
    for(int i = 0; i < log.curIndentLevel_ * 4; ++i) {
        log.os_ << ' ';
    }
    log.os_ << op;
    return log.os_;
}

int main() {
    Logger log(cout);
    log.increaseLevel();
    log << "Hello World!" << endl;
    log.decreaseLevel();
    log << "Hello World!" << endl;
    return 0;
}


下面是一个小变体,显示如何使用
操作符替代解决方案缩短编码:

#include <iostream>
#include <fstream>

class IndentClass {
    public:
        IndentClass();
        ~IndentClass();

    private:
        std::string IndentText;
        int _Indent;

    public:
        inline void SetIndentText(const char* Text);
        inline void Indent(int Amount);
        inline void SetIndent(int Amount);

        inline void ind (std::ostream& ofs);

        class Ind_t {
            public:
                IndentClass& state;
                Ind_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, Ind_t& ind);
        };
        class IndS_t {
            public:
                IndentClass& state;
                IndS_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndS_t& ind);
        };
        class IndE_t {
            public:
                IndentClass& state;
                IndE_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndE_t& ind);
        };
        Ind_t Ind;
        IndS_t IndS;
        IndE_t IndE;
};

IndentClass::IndentClass () : IndentText("    "), _Indent(0), Ind(*this), IndS(*this), IndE(*this) {

}

IndentClass::~IndentClass () {
}

void IndentClass::SetIndentText (const char* Text) {
    IndentText = Text;
}

void IndentClass::Indent (int Amount) {
    _Indent += Amount;
}

void IndentClass::SetIndent(int Amount) {
    _Indent = Amount;
}

void IndentClass::ind (std::ostream& ofs) {
    for (int i = 0;i < _Indent;i++) {
        ofs << IndentText;
    }
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::Ind_t& ind) {
    ind.state.ind(ofs);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndS_t& inds) {
    inds.state.ind(ofs);
    inds.state.Indent(1);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndE_t& inde) {
    inde.state.Indent(-1);
    inde.state.ind(ofs);
    return ofs;
}

int main () {
    IndentClass i;

    std::cout << i.IndS << "test" << std::endl;
    std::cout << i.Ind << "test" << std::endl;
    std::cout << i.IndE << "test" << std::endl;

    return 0;
}
#包括
#包括
类缩进类{
公众:
缩进类();
~IndentClass();
私人:
std::字符串缩进文本;
整数缩进;
公众:
内联void SetIndentText(常量字符*文本);
内联无效缩进(整数金额);
内联void SetIndent(整数金额);
内联空隙索引(标准::ostream和ofs);
类别索引{
公众:
阶级与国家;
Ind_t(IndentClass&_state):state(_state){
friend inline std::ostream&operator替代解决方案:

#include <iostream>
#include <fstream>

class IndentClass {
    public:
        IndentClass();
        ~IndentClass();

    private:
        std::string IndentText;
        int _Indent;

    public:
        inline void SetIndentText(const char* Text);
        inline void Indent(int Amount);
        inline void SetIndent(int Amount);

        inline void ind (std::ostream& ofs);

        class Ind_t {
            public:
                IndentClass& state;
                Ind_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, Ind_t& ind);
        };
        class IndS_t {
            public:
                IndentClass& state;
                IndS_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndS_t& ind);
        };
        class IndE_t {
            public:
                IndentClass& state;
                IndE_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndE_t& ind);
        };
        Ind_t Ind;
        IndS_t IndS;
        IndE_t IndE;
};

IndentClass::IndentClass () : IndentText("    "), _Indent(0), Ind(*this), IndS(*this), IndE(*this) {

}

IndentClass::~IndentClass () {
}

void IndentClass::SetIndentText (const char* Text) {
    IndentText = Text;
}

void IndentClass::Indent (int Amount) {
    _Indent += Amount;
}

void IndentClass::SetIndent(int Amount) {
    _Indent = Amount;
}

void IndentClass::ind (std::ostream& ofs) {
    for (int i = 0;i < _Indent;i++) {
        ofs << IndentText;
    }
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::Ind_t& ind) {
    ind.state.ind(ofs);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndS_t& inds) {
    inds.state.ind(ofs);
    inds.state.Indent(1);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndE_t& inde) {
    inde.state.Indent(-1);
    inde.state.ind(ofs);
    return ofs;
}

int main () {
    IndentClass i;

    std::cout << i.IndS << "test" << std::endl;
    std::cout << i.Ind << "test" << std::endl;
    std::cout << i.IndE << "test" << std::endl;

    return 0;
}
#包括
#包括
类缩进类{
公众:
缩进类();
~IndentClass();
私人:
std::字符串缩进文本;
整数缩进;
公众:
内联void SetIndentText(常量字符*文本);
内联无效缩进(整数金额);
内联void SetIndent(整数金额);
内联空隙索引(标准::ostream和ofs);
类别索引{
公众:
阶级与国家;
Ind_t(IndentClass&_state):state(_state){

friend inline std::ostream&Operator您不应该继承
std::ofstream
,而是提供一个。我曾尝试提供操纵器的
Ind
IndE
,但这需要存储额外的信息,因此我认为创建一个特殊版本的ofstream会很有效。这是一个更干净的解决方案注意,应该使用任何流(
cout
stringstream
fstream
)这里有一些关于如何编写I/O操纵器的更重要的链接:另外,对于重定向构造函数,使用类似于
模板子(T..和&v):父(std::forward(v){}
您不应该继承
std::ofstream
,而是提供一个。我尝试提供操纵器的
Ind
IndS
IndE
,但这需要存储额外的信息,因此我认为创建ofstream的特殊版本会很有效。这是一个更干净的解决方案,应该适用于任何stream(
cout
stringstream
fstream
)这里有一些关于如何编写I/O操纵器的更重要的链接:另外,对于重定向构造函数,使用类似于
模板子(T..和&v):父(std::forward(v){}
#include <iostream>
#include <fstream>

class IndentClass {
    public:
        IndentClass();
        ~IndentClass();

    private:
        std::string IndentText;
        int _Indent;

    public:
        inline void SetIndentText(const char* Text);
        inline void Indent(int Amount);
        inline void SetIndent(int Amount);

        inline void ind (std::ostream& ofs);

        class Ind_t {
            public:
                IndentClass& state;
                Ind_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, Ind_t& ind);
        };
        class IndS_t {
            public:
                IndentClass& state;
                IndS_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndS_t& ind);
        };
        class IndE_t {
            public:
                IndentClass& state;
                IndE_t (IndentClass& _state) : state(_state) {}
                friend inline std::ostream& operator<< (std::ostream& ofs, IndE_t& ind);
        };
        Ind_t Ind;
        IndS_t IndS;
        IndE_t IndE;
};

IndentClass::IndentClass () : IndentText("    "), _Indent(0), Ind(*this), IndS(*this), IndE(*this) {

}

IndentClass::~IndentClass () {
}

void IndentClass::SetIndentText (const char* Text) {
    IndentText = Text;
}

void IndentClass::Indent (int Amount) {
    _Indent += Amount;
}

void IndentClass::SetIndent(int Amount) {
    _Indent = Amount;
}

void IndentClass::ind (std::ostream& ofs) {
    for (int i = 0;i < _Indent;i++) {
        ofs << IndentText;
    }
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::Ind_t& ind) {
    ind.state.ind(ofs);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndS_t& inds) {
    inds.state.ind(ofs);
    inds.state.Indent(1);
    return ofs;
}

std::ostream& operator<< (std::ostream& ofs, IndentClass::IndE_t& inde) {
    inde.state.Indent(-1);
    inde.state.ind(ofs);
    return ofs;
}

int main () {
    IndentClass i;

    std::cout << i.IndS << "test" << std::endl;
    std::cout << i.Ind << "test" << std::endl;
    std::cout << i.IndE << "test" << std::endl;

    return 0;
}