c++结合使用成员函数和重载运算符来过滤传递到流的数据
我有一个复杂的嵌套层次结构的对象,需要在输出时进行过滤,这样只有满足特定条件的对象才会写入文件。
假设我有类 A,它包含对象 B 的 STL 向量数组,其中每个对象 B 包含对象 C 的 STL 向量数组。
现在所有聪明的事情都已完成,过滤结果需要写入文件:
class A
{
...
std::vector<B> bArray;
std::ostream & filterA(std::ostream &out, int param1,int param2, bool param3)
{
if (param1>0)
{
for (intcurB=0;curB!=bArray.size();curB++)
{
out << bArray.at(curB).filterB(param2,param3);
}
else if (param1<=0) out << "";
return out;
}
};
class B
{
std::vector<C> cArray; std::ostream & filterB(std::ostream &out, int param2, bool param3)
{
if (param2<0)
{
for (int curC=0;curC!=cArray.size();curC++)
{
out << cArray.at(curC);
}
}
else if (param2>0) out << "";
else if(param3) out << "\nInvalid object\n";
else out << "";
return out;
}
};
class C {
bool isSet;
std::vector<int> intArray;
... };
std::ostream & operator <<(std::ostream & out, C &c)
{
if(c.isSet)
{
for (int curInt=0;curInt!=intArray.size();curInt++)
{
out << c.intArray.at(curInt) << " ";
}
out << "\n";
}
else if (!c.isSet) out << "";
return out;
}
int main()
{
A aObject;
....
// Now lets write filtered objects to file
std::ofstream outputFile("/home/user/test.txt");
if (outputFile.is_open())
{
outputFile << aObject.filterA(outputFile,1,-1,false);
outputFile.close();
}
return 0;
}
代码有效,即它编译并运行,但 ostream 对象的地址也被写入文件!
我的问题是
- 一般方法是否可取?
- 有更好的解决方案(可能使用特征)吗?
I have a complex nested hierachy of objects which I need to filter at output, sucht that only objects which meet certain criteria are written to file.
Suppose I have class A, which comprises an STL vector array of objects B, where each object B comprises an STL vector array of objects C.
Now all the clever stuff has been done and the filtered results need to be written to file:
class A
{
...
std::vector<B> bArray;
std::ostream & filterA(std::ostream &out, int param1,int param2, bool param3)
{
if (param1>0)
{
for (intcurB=0;curB!=bArray.size();curB++)
{
out << bArray.at(curB).filterB(param2,param3);
}
else if (param1<=0) out << "";
return out;
}
};
class B
{
std::vector<C> cArray; std::ostream & filterB(std::ostream &out, int param2, bool param3)
{
if (param2<0)
{
for (int curC=0;curC!=cArray.size();curC++)
{
out << cArray.at(curC);
}
}
else if (param2>0) out << "";
else if(param3) out << "\nInvalid object\n";
else out << "";
return out;
}
};
class C {
bool isSet;
std::vector<int> intArray;
... };
std::ostream & operator <<(std::ostream & out, C &c)
{
if(c.isSet)
{
for (int curInt=0;curInt!=intArray.size();curInt++)
{
out << c.intArray.at(curInt) << " ";
}
out << "\n";
}
else if (!c.isSet) out << "";
return out;
}
int main()
{
A aObject;
....
// Now lets write filtered objects to file
std::ofstream outputFile("/home/user/test.txt");
if (outputFile.is_open())
{
outputFile << aObject.filterA(outputFile,1,-1,false);
outputFile.close();
}
return 0;
}
The code works i.e. it compiles and runs but the address of the ostream object is written to file too!
My questions are
- Is the general methodology advisable?
- Is there a better solution (possibly using traits)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在寻找代码审查吗?
有几件事我要纠正。
类似地,B 作为 C 的集合,尽管这里它必须是指向向量的指针而不是引用,因为 B 必须可分配到向量中(与 A 不同,A 本身不是向量元素)。
您可以使用循环或 BOOST_FOREACH 算法。无论如何,您的循环构造都不是最好的。使用迭代器稍微好一些。如果使用索引,则使用 size_t 或 vector::size_type 作为索引。最好在循环外或在 for 的第一部分计算 size(),例如
for( std::vector::size_type i = 0, len = v.size(); i != len ; ++i )
不要使用 at()。您知道您的索引没有超出范围。如果必须使用此构造,请优先使用运算符[]。
filterA 和 filterB 都不修改它们的类,因此使它们成为 const 成员函数。
流式传输空字符串只是毫无意义的代码。如果您有一个可能为空但 os << 的字符串变量,这是一回事。 "" 什么也没实现。
Are you looking for a code-review?
There are a few things I would correct there.
Similarly B as a collection of C, although here it must be a pointer to the vector not a reference as B must be assignable to be in a vector (unlike with A which is not itself a vector element).
You could use an algorithm to loop or BOOST_FOREACH. In any case your looping construct is not the best. Slightly better to use iterators. If you use indexes then size_t or vector::size_type as the index. Better to calculate size() once outside the loop or in the first part of the for eg
for( std::vector<B>::size_type i = 0, len = v.size(); i != len; ++i )
Do not use at(). You know your indexes are not out of bounds. Prefer operator[] if you have to use this construct.
Neither filterA nor filterB modify their classes so make them const member functions.
Streaming empty strings is just pointless code. It's one thing if you have a string variable that might be empty but
os << ""
achieves nothing.