所以我想编写一个可以像这样使用的缩进输出类:
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;
}
所以我认为这有一些问题:
它无法编译。 no match for 'operator<<' (operand types are 'std::ofstream {aka std::basic_ofstream<char>}' and '<unresolved overloaded function type>') ofs << Ind; candidates are:
的错误等等等等
我没有覆盖所有构造函数。有没有办法做到这一点?我想我只需重写所有构造函数来执行IndentText = " ";
并委托重载的构造函数
有人可以帮我吗?谢谢!
答案 0 :(得分: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操纵器样式免费功能。
答案 1 :(得分:2)
替代解决方案:
#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;
}