1

したがって、次のように使用できるインデント出力クラスを作成したいと思います。

Debug f;
f.open("test.txt");
f << Debug::IndS << "Start" << std::endl;
f << Debug::Ind << "test" << std::endl;
f << Debug::IndE << "End" << std::endl;

出力は次のとおりです。

Start
    test
End

したがって、IndS は現在のインデントを出力してインデントを増やし、Ind は現在のインデントを出力し、IndE はインデントを減らして現在のインデントを出力します。私はそれを次のように作成しようとしました:

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;
}

したがって、これにはいくつかの問題があると思います。

  1. コンパイルされません。no match for 'operator<<' (operand types are 'std::ofstream {aka std::basic_ofstream<char>}' and '<unresolved overloaded function type>') ofs << Ind; candidates are:何とかエラー

  2. すべてのコンストラクターをオーバーライドするわけではありません。これを行う方法はありますか?IndentText = " ";すべてのコンストラクターを書き直して、オーバーロードされたコンストラクターをデリゲートする必要があると思います

誰かがこれで私を助けてくれますか? ありがとう!

4

2 に答える 2

3

通常、継承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;
}

出力

    Hello World!
Hello World!

ライブサンプル


operator<<()オーバーロードを使用してコーディングを短縮する方法を示す、少し変形したものを次に示します。

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

    // ... as before ...        
};

int main() {
    Logger log(cout);

    log.increaseLevel() << "Hello World!" << endl;
    log.decreaseLevel() << "Hello World!" << endl;
    return 0;
}

ライブサンプル

同じ方法で追加の I/O マニピュレータ スタイル フリー関数を提供できます。

于 2014-08-09T10:04:56.173 に答える