Sponsored Content
Top Forums Programming passing object to function, columns class Post 302513540 by LMHmedchem on Wednesday 13th of April 2011 02:01:16 PM
Old 04-13-2011
Well I have something that works. What I ended up doing is loading all of the data to the objects as string. I plan to do the conversion from string to whatever as a second step. That will simplify the loading functions, since they will only have to deal with one type. I think I can do conversion as a class method that will read the string vector in the object and do the conversion to either the int vector or the float vector. In some cases it stays as string.

Here is the code,
Header file,
Code:
class col_metadata {
public:
   // initialize class members
   col_metadata()
      : scaleMin(0.0), scaleMax(0.0),
        content(""), type(""), scale_type(""),
        strScaleMin(""), strScaleMax(""),
        header("") { }

   float scaleMin, scaleMax;
   std::string content, type, scale_type,
               strScaleMin, strScaleMax,
               header;
};

class column_data {
public:
   // initialize class members
   column_data()
      : header("") { }

   std::string header;
   std::vector<std::string> inDtaStr;
   std::vector<char> inputDataChar;
   std::vector<int> inputDataInt;
   std::vector<float> inputDataFloat;
};

main file,
Code:
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include "columns.h"

using namespace std;

// global declarations
   // declare vector of col_metadata objects
   std::vector<col_metadata> metadata;
   // declare vector of column_data objects
   std::vector<column_data> columns;

// functions
// creates a data object and meta data object for each column
int createColObjs( stringstream &colsRowStream ){
   std::string rowCell;
   // parse header row into cells, tab delimiter
   while(getline(colsRowStream,rowCell,'\t')) {
      // create new column data object
      col_metadata newColMeta;  metadata.push_back(newColMeta);
      // create new column data object
      column_data newCol;  columns.push_back(newCol);
   }
   // clear the buffer
   colsRowStream.clear();
}

// accepts a stringstream and parses the data in to columns
int metadata_row_toCol( stringstream &colsRowStream, 
                        std::vector<col_metadata>& metadata,
                        std::string col_metadata::* var ){
   int i = 0;
   std::string rowCell;
   // parse header row into cells, tab delimiter
   while(getline(colsRowStream,rowCell,'\t')) {
      metadata[i].*var = rowCell;
      i++;
   }
   // clear the buffer
   colsRowStream.clear();
}

// accepts a stringstream and parses the data in to columns
int header_row_toCol( stringstream &colsRowStream, 
                    std::vector<column_data>& columns,
                    std::string column_data::* var ){
   int i = 0;
   std::string rowCell;
   // parse header row into cells, tab delimiter
   while(getline(colsRowStream,rowCell,'\t')) {
      columns[i].*var = rowCell;
      i++;
   }
   // clear the buffer
   colsRowStream.clear();
}

// accepts a stringstream and parses the data in to columns
int data_row_toCol( stringstream &colsRowStream, 
                    std::vector<column_data>& columns ){
   int i = 0;
   std::string rowCell;
   // parse header row into cells, tab delimiter
   while(getline(colsRowStream,rowCell,'\t')) {
      columns[i].inDtaStr.push_back(rowCell);
      i++;
   }
   // clear the buffer
   colsRowStream.clear();
}


int main(int argc, char **argv) {

// declarations for args
   // file names
   int cmdArguments;
   std::string colsInFile, splitsInFile, outputFile;

//  Parse command line arguments
while ((cmdArguments = getopt (argc, argv, "c:i:o:d:h")) != -1)
   switch (cmdArguments)
   {
      case 'c':
         colsInFile = optarg;
      break;
      case 'i':
         splitsInFile = optarg;
      break;
      case 'o':
         outputFile = optarg;
      break;
      case 'd':
         //set delimiter;
      break;
      case 'h':
         std::cout << std::endl; // print help blurb
         exit(0);
      break;
   }

// check args
   if(splitsInFile.length() == 0) {
      std::cout << "  -> no input file was specified" << std::endl;
      return(-1);
   }

// declarations
   int i; // loop iterator
   std::string newSplitsLine, rowCell, loadvar;
   std::vector<std::string> storeSplitsRows;    // storage structure for input rows
   stringstream colsRowStream;

// read input file
   // create an input stream and open the splitsInFile file
   ifstream splitsInput;
   splitsInput.open( splitsInFile.c_str() );

   // read innput file and store
   while(getline(splitsInput,newSplitsLine)) {
      // remove '\r' EOL chars
      newSplitsLine.erase (remove(newSplitsLine.begin(),newSplitsLine.end(),'\r') , newSplitsLine.end());
      // store row data in vector of string
      storeSplitsRows.push_back(newSplitsLine);
   }

// create objects to store data and meta data
   //use first row to create objects for each col
   colsRowStream << storeSplitsRows[0];
   createColObjs ( colsRowStream );

// load metadata into metadata objects
   // declare pointer to class data member, this is used to tell the loading
   // function where the data goes in the object
   std::string col_metadata::*var;

   // load information from metadata row 0 to metadata[i].content
   colsRowStream << storeSplitsRows[0];
   //set pointer to metadata.content
   var = &col_metadata::content;
   // call func to load row 0 data to content
   metadata_row_toCol( colsRowStream, metadata, var );

   // load information from metadata row 1
   colsRowStream << storeSplitsRows[1];
   var = &col_metadata::type; // load type row
   metadata_row_toCol( colsRowStream, metadata, var );

   // load information from metadata row 2
   colsRowStream << storeSplitsRows[2];
   var = &col_metadata::scale_type; // load scale_type row
   metadata_row_toCol( colsRowStream, metadata, var );

   // load information from metadata row 3
   colsRowStream << storeSplitsRows[3];
   var = &col_metadata::strScaleMin; // load strScaleMin row
   metadata_row_toCol( colsRowStream, metadata, var );

   // load information from metadata row 4
   colsRowStream << storeSplitsRows[4];
   var = &col_metadata::strScaleMax; // load strScaleMax row
   metadata_row_toCol( colsRowStream, metadata, var );

   // load information from metadata row 5
   colsRowStream << storeSplitsRows[5];
   var = &col_metadata::header;  // load header row
   metadata_row_toCol( colsRowStream, metadata, var );

   // print loaded data for checking
   std::cout << std::endl;
   for (i=0; i<metadata.size(); i++) {
      std::cout << "metadata[" << i << "].content      " << metadata[i].content << std::endl;
      std::cout << "metadata[" << i << "].type         " << metadata[i].type << std::endl;
      std::cout << "metadata[" << i << "].scale_type   " << metadata[i].scale_type << std::endl;
      std::cout << "metadata[" << i << "].strScaleMin  " << metadata[i].strScaleMin << std::endl;
      std::cout << "metadata[" << i << "].strScaleMax  " << metadata[i].strScaleMax << std::endl;
      std::cout << "metadata[" << i << "].header       " << metadata[i].header << std::endl;
      std::cout << std::endl;
   }

// load data to data objects
   // load header row
   int metadata_rows, j;
   std::string column_data::*varCol;
   std::vector<std::string> column_data::*stringVar;

   // number of rows of metadata before header
   metadata_rows = 5;

   // load header row data
   colsRowStream << storeSplitsRows[metadata_rows];
   varCol = &column_data::header;  // load header row
   header_row_toCol( colsRowStream, columns, varCol );

   for(i=metadata_rows+1; i<storeSplitsRows.size(); i++ ) {
      // load first row to stringstream
      colsRowStream << storeSplitsRows[i];
      data_row_toCol( colsRowStream, columns );
   }

   // print loaded data for checking
   std::cout << std::endl;
   for (i=0; i<columns.size(); i++) {
      std::cout << "columns[" << i << "].header       " << columns[i].header << std::endl;
      for (j=0; j<columns[0].inDtaStr.size(); j++) {
         std::cout << "columns[" << i << "].inDtaStr[" << j << "]  " << columns[i].inDtaStr[j] << std::endl;
      }
      std::cout << std::endl;
   }

}

What I did to load the metadata was to declare a pointer to class data member,
Code:
    std::string col_metadata::*var;

Then in the function definition, I pass a reference to the vector of objects, and also the pointer to data member,
Code:
 int metadata_row_toCol( stringstream &colsRowStream, 
                         std::vector<col_metadata>& metadata,
                         std::string col_metadata::*  var );

As far as I can tell, the function just knows there will be a pointer, but doesn't care which data member it points to, or which object. In the loading fucntion, it's just,
Code:
      metadata[i].*var = rowCell;

Then I select a row to process,
Code:
    colsRowStream << storeSplitsRows[0];

point *var to what I want (the content string here, which is in row 0)
Code:
   var = &col_metadata::content;

and call the loading function with the row, the vector of objects, and the pointer.
Code:
metadata_row_toCol( colsRowStream, metadata, var );

This lets me load each row to a different data member by changing the pointer. As far as I can tell, the only limitation is that the pointer is declared as a string, so I couldn't point to an int data member, etc. I could declare different kinds of pointer if I needed to.

For the data rows, I am loading everything as string, so the destination in the objects is always the same. I am using push_back to dynamically size the vectors.

I think that logically these functions should be class methods, but I'm not sure how to go about adding them. I seem to remember issues when referencing thing from inside a class. I also need to add methods for doing the translation from string to int and string to float.

Do you see anything grievously wrong with how I'm going about this? I am hoping to develop some nice reusable code that I can implement in other apps that use similar data. I think I can dispense with storing the entire file on input, since I am storing as string anyway, or I can just clear the storage vector when I am done with it? Is there some point at which I need to become concerned with resource allocation? I have tried the above on an input file of 250 cols and ~16,000 rows. The app uses about 135MB of RAM and takes 1min 8 seconds to complete. This includes writing the data back to an output file in an inefficient method.

LMHmedchem
 

10 More Discussions You Might Find Interesting

1. Programming

Listing function exports from object file

Is it possible to view all the functions exported by a given object file? "dump -tv" comes the closest, but what exactly am I looking for to determine whether the symbol exists in the object file? Essentially, I have a library that requires a call to "xdr_sizeof" and the compile is failing... (5 Replies)
Discussion started by: DreamWarrior
5 Replies

2. Programming

How to make a function friend to both base and derived class

Hi, I have a base class and derived a class from the base class, i want to print & read the data for the object created for the derived class,so i have overloaded both the << and >> operators and also have done the foward declaration. Below is the code snippet, #include <iostream> class... (3 Replies)
Discussion started by: ennstate
3 Replies

3. Shell Programming and Scripting

Passing global variable to a function which is called by another function

Hi , I have three funcions f1, f2 and f3 . f1 calls f2 and f2 calls f3 . I have a global variable "period" which i want to pass to f3 . Can i pass the variable directly in the definition of f3 ? Pls help . sars (4 Replies)
Discussion started by: sars
4 Replies

4. Programming

Handling a signal with a class member function

Hello, i am using the sigaction function to handle the SIGCHLD signal.Is it possible to use a class member function as the handler function (the sa_handler member of the sigaction structure)? The function's signature is: void (*sa_handler)(int);so i don't think i can use a static member function... (2 Replies)
Discussion started by: Zipi
2 Replies

5. Shell Programming and Scripting

How to Call external function in .C or .So (Shared Object)

Hi, Anybody know any way to Call with Shell Script an external function wrote in .C or .So (Shared Object) on AIX enviroment and returning parameters of .C or .SO to Shell Script? Tks!! (6 Replies)
Discussion started by: rdgsantos
6 Replies

6. Programming

question about function object

I have a code as following: #include <iostream> #include <algorithm> #include <list> using namespace std; //the class Nth is a predicates class Nth{ private: int nth; int count; public: Nth(int n):nth(n),count(0){} bool operator()(int){ ... (2 Replies)
Discussion started by: homeboy
2 Replies

7. UNIX and Linux Applications

opends- help with custom object class

we have 2.2.0 of opends running on RedHat 2.6.21 and we're trying to setup a structure that will suit our needs. One of the things we'd like to do is create our own custom object classes based off some of the existing ones you get out of the box. The opends documentation covers this here (sorry, it... (1 Reply)
Discussion started by: snafu
1 Replies

8. Programming

Created a wrapper for a function in a class.

I have a class called Parsing with the following function. I want to create a wrapper for it, so that I call it using GetReal rather than GetFloat. Bit confused on how to do this. class Parsing { private: int Length; // int Ptr; ... (3 Replies)
Discussion started by: kristinu
3 Replies

9. Programming

How to initialize an object with another object of different class?

How to initialize an object of class say "A", with an object of type say "B". The following code give the error message "error: conversion from âAâ to non-scalar type âBâ requested" #include <iostream> using namespace std; class B; class A{ public: A() { cout <<"\nA()" << endl; } ... (1 Reply)
Discussion started by: techmonk
1 Replies

10. Programming

C++ : Base class member function not accessible from derived class

Hello All, I am a learner in C++. I was testing my inheritance knowledge with following piece of code. #include <iostream> using namespace std; class base { public : void display() { cout << "In base display()" << endl; } void display(int k) {... (2 Replies)
Discussion started by: anand.shah
2 Replies
All times are GMT -4. The time now is 08:25 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy