С ++ сочетает использование функций-членов и перегруженных операторов для фильтрации данных, передаваемых в поток - PullRequest
0 голосов
/ 18 января 2011

У меня сложная вложенная иерархия объектов, которые мне нужно отфильтровать при выводе, чтобы в файл записывались только объекты, соответствующие определенным критериям.

Предположим, у меня есть класс A, который содержит векторный массив объектов STL объектов B, где каждый объект B содержит векторный массив объектов STL объектов C.

Теперь все умные вещи сделаны, и отфильтрованные результаты должны быть записаны в файл:

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 также записывается в файл!

Мои вопросы

  1. Целесообразна ли общая методология?
  2. Есть ли лучшее решение (возможно, с использованием признаков)?

1 Ответ

1 голос
/ 18 января 2011

Вы ищете код-обзор?

Есть несколько вещей, которые я бы исправил там.

  1. Имеет ли A какую-либо цель, кроме форматирования печати для массива B? Живет ли Б собственное существование? Если это так, пусть A содержит константную ссылку на вектор B, а не копирует его.

Аналогично B как совокупность C, хотя здесь это должен быть указатель на вектор, а не ссылка, поскольку B должен быть назначаем, чтобы находиться в векторе (в отличие от A, который сам не является элементом вектора).

Вы можете использовать алгоритм для цикла или BOOST_FOREACH. В любом случае ваша циклическая конструкция не самая лучшая. Чуть лучше использовать итераторы. Если вы используете индексы, то size_t или vector :: size_type в качестве индекса. Лучше рассчитать size () один раз за пределами цикла или в первой части, например, для

for( std::vector<B>::size_type i = 0, len = v.size(); i != len; ++i )

Не использовать в (). Вы знаете, что ваши индексы не выходят за пределы. Предпочитайте оператор [], если вам нужно использовать эту конструкцию.

Ни filterA, ни filterB не изменяют свои классы, поэтому делают их постоянными функциями-членами.

Потоковая передача пустых строк - просто бессмысленный код. Одно дело, если у вас есть строковая переменная, которая может быть пустой, но os << "" ничего не достигает.

...