Link to home
Start Free TrialLog in
Avatar of antoniogm
antoniogm

asked on

Pulling subclasses of a superclass off of a vector....


My problem is the following:

I define a superclass GapFunction, which is meant to encompass families of probability distributions. Those distributions (gaussian, multinomial, etc.) are subclassed to GapFunction and overload a method or two.

Within MMotif (reproduced below), I define vector<GapFunction> gaps, and then proceed to push on various subclasses of GapFunction on to it. However, when I pull them off the vector and call a method, it defaults to the skeleton methods in GapFunction, rather than the overloaded methods defined in the various subclasses. In Java, I would cast the pulled-off object to the subclass and go from there, but in C++ I am somewhat lost. All help appreciated...Antonio.

class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<Multinomial> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Multinomial m1(MMotif.min, MMotif.max);
    gaps.push_back(m1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(m);
          }         
          //    else if(functype==1){
          // Gaussian g(strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL));
          // gaps.push_back(g);
          //}
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Multinomial m2(min, max);
     gaps.push_back(m2);
     //cout << "nullity at end is "<< gaps[gaps.size()-1].isFree() << endl;
     readFile.close();
  }

Avatar of jkr
jkr
Flag of Germany image

>>I would cast the pulled-off object to the subclass and go from there, but in C++ I am somewhat lost

In C++, you'd make the 'GapFunction' methods 'virtual' in order to achieve the desired effect.
Avatar of Dexstar
Dexstar

antoniogm:

> Within MMotif (reproduced below), I define vector<GapFunction> gaps, and then
> proceed to push on various subclasses of GapFunction on to it. However, when
> I pull them off the vector and call a method, it defaults to the skeleton
> methods in GapFunction, rather than the overloaded methods defined in the
> various subclasses. In Java, I would cast the pulled-off object to the subclass
> and go from there, but in C++ I am somewhat lost. All help appreciated...Antonio.

In C++, when you want to overload a method, you have to declare that method as being "virtual".  If you've already done that, then post the class definitions for GapFunction and Multinomial.

BTW, you said that declared "vector<GapFunction> gaps", but I see "vector<Multinomial> gaps".  Which is it supposed to be?

Hope that helps,
Dex*
Lil' explanation from the VC++ docs:

Virtual Function
C++ Specific —>

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

END C++ Specific

Example 1

class WageEmployee
{
public:
   virtual float computePay();
};

class SalesPerson : public WageEmployee
{
public:
   float computePay();
};
You can execute different versions of computePay( ) depending on the type of object you're calling it for.

Example 2

WageEmployee aWorker;
SalesPerson aSeller;
WageEmployee *wagePtr;

wagePtr = &aWorker;
wagePtr->computePay();   // call WageEmployee::computePay
wagePtr = &aSeller;
wagePtr->computePay();   // call SalesPerson::computePay
The virtual keyword is needed only in the base class's declaration of the function; any subsequent declarations in derived classes are virtual by default.

A derived class's version of a virtual function must have the same parameter list and return type as those of the base class. If these are different, the function is not considered a redefinition of the virtual function. A redefined virtual function cannot differ from the original only by return type.
Here's is a similar kind of question and some useful discussion on the same

https://www.experts-exchange.com/questions/20783912/Overloading-inherited-functions.html


Hope this helps
Avatar of antoniogm

ASKER

I still get compilation errors. I am posting GapFunction.h,  Null.h ( a null prob. dist. that always returns 0.0, and with maximal range of inputs), and the new MMotif.h.


#ifndef GF_FLAG
#define GF_FLAG
#include <iostream>
#include <string>
class GapFunction{
public:

  virtual double func(int i);
  virtual int lowerBound();
  virtual int upperBound();

};
#endif

#ifndef NULL_FLAG
#define NULL_FLAG
#include <iostream>
#include <string>
#include "GapFunction.h"
#include <math.h>
#include <vector>
#include <limits.h>

class Null: public GapFunction
{
 public:
  Null(){;}
  double func(int i){
    return 0.0;
  }
  int lowerBound(){
    cout << "calling lowerbound in null\n";
    return 1;
  }
  int upperBound(){
    return INT_MAX;
  }
};
#endif

#include <string>
#include <map>
#include <math.h>
#include <vector>
//#include <ot/util/StringTokenizer.h>
#include "PWM.h"
#include "GapFunction.h"
#include "Gaussian.h"
#include "Free.h"
#include "Multinomial.h"
#include "Null.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <limits.h>

using namespace std;
class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<GapFunction> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Null n1;
    gaps.push_back(n1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(m);
          }         
              else if(functype==1){
           Gaussian g(strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL));
           gaps.push_back(g);
          }
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Null n2;
     gaps.push_back(n2);
     //cout << "nullity at end is "<< gaps[gaps.size()-1].isFree() << endl;
     readFile.close();
  }
  double scoreSeq(const std::string str){
    return score(pwms.size()-1, gaps.size()-1, str);
  }
        
            
            
  double score(int m, int g, const std::string& str){
   
    cout << "running with motif " << m<< " gap " << g << " str  " << str << endl;
    if(g==0){
      cout << "in last gap"<<endl;
      return 0.0;
    }
    else if(str.length()==0){
      cout << "string ended\n";
      return -10000;
    }
    else{
      if(g==m+1){

      cout <<"in gap mode with gaps " << gaps.size()<< "\n";
      int lower=gaps[g].lowerBound();
      int upper=gaps[g].upperBound();
      
      double max=-10000;
      double gapvalue=-10000;
      
      cout << " lower upper " << lower << " " << upper << endl;
      for(int i=lower; i<=upper; i++){
        gapvalue=gaps[g].func(i) + score(m, g-1, str.substr(i, str.length()-1));
        cout << "value at gap "<< i << " " << gapvalue << endl;
        if(gapvalue>max){
            //      cout<< "doing comparison\n";
          max=gapvalue;
        }
      }
      return max;
      
      }else if(g==m){
      
      
      double pwmvalue=-10000;
      pwmvalue=pwms[m].score( str.substr(0, pwms[m].length() ) )
        + this->score( m-1, g, str.substr(pwms[m].length(), str.length()-pwms[m].length()));
      return pwmvalue;
      }
     
     
      /*if(pwmvalue>gapvalue){
        cout<< "went with the pwm\n";
         return pwmvalue;
      }else{
         cout<< "went with the gap\n";
         return gapvalue;
      }  
      
          //cout << gaps[l].func(k)<< endl;
          //cout << pwms[l].score( str.substr(0, pwms[l].length() ) )<< endl;
          return MMotif::max(
                 
          gaps[l].func(k + 1 ) - gaps[l].func(k)+ score(l, k + 1, str.substr(1, str.length()-1)),
          pwms[l].score(str.substr(0, pwms[l].length() ) )
                 
          
          + this->score( l - 1, 0, str.substr(pwms[l].length(), str.length()-pwms[l].length()))
          ); //  max
          
          }*/
    }
     
  }
    double max(double first, double second){
      if(first>=second){
      cout << "returning first arg " << first << endl;
      return first;
    }else{
      cout << "returning second arg " << second << endl;
      return second;
    }
  }
     private:
 

};




>>I still get compilation errors

Um, my crystal ball is still on repair - what errors?
g++ score.cpp
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0x8): undefined reference to `GapFunction::func(int)'
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0xc): undefined reference to `GapFunction::lowerBound(void)'
/tmp/ccSDUD7r.o(.gnu.linkonce.d.__vt_8Gaussian+0x10): undefined reference to `GapFunction::upperBound(void)'
/tmp/ccSDUD7r.o: In function `GapFunction::GapFunction(void)':
/tmp/ccSDUD7r.o(.GapFunction::gnu.linkonce.t.(void)+0x8): undefined reference to `GapFunction virtual table'
/tmp/ccSDUD7r.o: In function `GapFunction::GapFunction(GapFunction const &)':
/tmp/ccSDUD7r.o(.GapFunction::gnu.linkonce.t.(GapFunction const &)+0xb): undefined reference to `GapFunction virtual table'
/tmp/ccSDUD7r.o: In function `Gaussian type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf8Gaussian+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf8Gaussian+0x18): undefined reference to `GapFunction type_info node'
/tmp/ccSDUD7r.o: In function `Multinomial type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf11Multinomial+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf11Multinomial+0x18): undefined reference to `GapFunction type_info node'
/tmp/ccSDUD7r.o: In function `Null type_info function':
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf4Null+0x10): undefined reference to `GapFunction type_info function'
/tmp/ccSDUD7r.o(.gnu.linkonce.t.__tf4Null+0x18): undefined reference to `GapFunction type_info node'
collect2: ld returned 1 exit status


To me at least, not particularly informative....
Even though the 'GapFunction' members do nothing, they either have to be 'pure virtual' or you have to provide a minimal implementation, e.g.

// minimal impl.
class GapFunction{
public:

 virtual double func(int i) { return 0.0;};
 virtual int lowerBound() { return 0;};
 virtual int upperBound(){ return 0;};
};

// pure virtual
class GapFunction{
public:

 virtual double func(int i) = 0;
 virtual int lowerBound() = 0;
 virtual int upperBound() = 0;
};
I made the above changes, and now get something of the form:

cd /home/agm/C++/MPattern/
g++ score.cpp
/usr/include/g++-3/stl_construct.h: In function `void construct (_T1 *,
const _T2 &) [with _T1 = GapFunction, _T2 = GapFunction]':
/usr/include/g++-3/stl_vector.h:321:   instantiated from `vector<_Tp, _Alloc>::push_back (const _Tp &) [with _Tp = GapFunction, _Alloc = allocator<GapFunction>]'
MMotif.h:42:   instantiated from here
/usr/include/g++-3/stl_construct.h:48: cannot allocate an object of
type `GapFunction'
/usr/include/g++-3/stl_construct.h:48:   since the following virtual
functions are abstract:
GapFunction.h:10:       int GapFunction::upperBound ()
GapFunction.h:9:       int GapFunction::lowerBound ()
GapFunction.h:8:       double GapFunction::func (int)
/usr/include/g++-3/stl_vector.h: In method `void vector<_Tp,
_Alloc>::_M_insert_aux (_Tp *, const _Tp &) [with _Tp = GapFunction,
_Alloc = allocator<GapFunction>]':
/usr/include/g++-3/stl_vector.h:325:   instantiated from `vector<_Tp, _Alloc>::push_back (const _Tp &) [with _Tp = GapFunction, _Alloc = allocator<GapFunction>]'
MMotif.h:42:   instantiated from here
/usr/include/g++-3/stl_vector.h:593: cannot declare variable `__x_copy'
to be of type `GapFunction'
/usr/include/g++-3/stl_vector.h:593:   since type `GapFunction' has
abstract virtual functions
/usr/include/g++-3/stl_vector.h:593: cannot allocate an object of type
`GapFunction'
/usr/include/g++-3/stl_vector.h:593:   since type `GapFunction' has
abstract virtual functions

OK, I forgot about that - this way, you should use the "minimal" approach
Ok, the hackery works now and the compiler doesn't complain, but I am still getting the same fundamental error of the function call going to the superclass rather than the subclass. The below test script:

#include <iostream>
#include "Null.h"
using namespace std;
void main(){
  Null n;
  cout<< n.lowerBound()<<endl;
  cout<< n.upperBound()<<endl;
  vector<GapFunction> gaps;
  gaps.push_back(n);
  cout<<gaps[0].lowerBound()<< endl;
   

}

returns:

1
2147483647
0


Make it read

include <iostream>
#include "Null.h"
using namespace std;
void main(){
 Null n;
 cout<< n.lowerBound()<<endl;
 cout<< n.upperBound()<<endl;
 vector<GapFunction&> gaps; // <--!!!
 gaps.push_back(n);
 cout<<gaps[0].lowerBound()<< endl;
}

As the above explanation says:

"A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function."

As you were storing instances of 'GapFunction' objects and not pointers or references, you were still calling the base class member functions.

I do that and get:

cd /home/agm/C++/MPattern/
g++ test2.cpp
/usr/include/g++-3/stl_vector.h: In instantiation of `_Vector_alloc_base<GapFunction &, allocator<GapFunction &>, true>':
test2.cpp:8:   instantiated from `_Vector_base<GapFunction &, allocator<GapFunction &> >'
test2.cpp:8:   instantiated from `vector<GapFunction &, allocator<GapFunction &> >'
test2.cpp:8:   instantiated from here
/usr/include/g++-3/stl_vector.h:87: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:88: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:89: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:93: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:95: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h: In instantiation of `vector<GapFunction &, allocator<GapFunction &> >':
test2.cpp:8:   instantiated from here
/usr/include/g++-3/stl_vector.h:159: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:160: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:161: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:162: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:163: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:164: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:172: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:172: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:173: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:173: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:589: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:621: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:195: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:196: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:197: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:198: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:201: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:201: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:203: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:203: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:205: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:205: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:207: forming pointer to reference type
`GapFunction &const'
/usr/include/g++-3/stl_vector.h:207: template argument 1 is invalid
/usr/include/g++-3/stl_vector.h:218: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:219: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:226: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:530: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:314: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:315: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:316: forming reference to reference
type `GapFunction &'
/usr/include/g++-3/stl_vector.h:317: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:319: forming reference to reference
type `GapFunction &const'
/usr/include/g++-3/stl_vector.h:341: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:351: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:364: forming pointer to reference type
`GapFunction &'
/usr/include/g++-3/stl_vector.h:364: confused by earlier errors,
bailing out

Compilation exited abnormally with code 1 at Fri Oct 31 15:40:19


Look, at this point maybe we need faster communication to resolve this rather than bouncing slowly via the site. I am antoniofgm on aim, or malvoglio on ymessenger. Or email me directly at agm at socrates.berkeley.edu
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry, direct email is against the site rules :o)
Pointer approach worked. Thanks so much for your time and instantaneous responses...500 points on the way.
Just never ends....

Now it throws a segmentation fault. Seems like it doesnt' like calling functions on objects from the vector. Note that I do a test at the end of the constructor to see that the Null GapFunction works. But then later does not work inside of score()....

class MMotif{
public:
  vector<PWM> pwms;
  PWM backgr;
  vector<GapFunction*> gaps;
  string MATRIX_DEL;
  string FUNC_DEL;
  static int const MMotif::maxlength=1000;
  static int const MMotif::minlength=1;
  /*MMotif(const vector<PWM>& p,
         const vector<GapFunction>& g) {
    if (p.size() != g.size() + 1) {
      std::cout << "PWMs and GapFunctions not numbered accordingly" << std::endl;

    } else {
      pwms.assign(p.begin(), p.end());  // no need for a loop; use stl
      gaps.assign(g.begin(), g.end());
    }
   
    }*/
  MMotif(char *name){
    MATRIX_DEL="M";
    FUNC_DEL="F";
    Null n1;
    gaps.push_back(&n1);
    //cout << "multinomial nullity is " << gaps[0].isFree()<<endl;
    ifstream readFile(name, ios::in);
    char s[100];     // declares variable to read data from file
    vector<string> matrixlines;
    bool matricing=false;
    bool done=false;
     while(!done) {
       //       cout << readFile.eof() << endl;
       readFile.getline(s, 100);
        string line(s);
        // cout << line << endl;
        string buf; // Have a buffer string
        stringstream ss(line); //insert the string into a stream
     
        vector<string> tokens; // Create vector to hold our words
     
        while (ss >> buf){
          tokens.push_back(buf);
        }
        //string::size_type firstwhitespace=line.find_first_of(" ", 0);
        //string type=line.substr(0, firstwhitespace);
        //string trunc_line=line.substr(firstwhitespace, line.size());
        string type=tokens[0];
        
        if(matricing){
          if(type==MATRIX_DEL){
            PWM pwm(matrixlines);
            pwms.push_back(pwm);
            matricing=false;
            matrixlines.erase(matrixlines.begin(), matrixlines.end());
            //            cout << "erase matrices\n";
          }
          else{
            matrixlines.push_back(line);
          }
        }else if(type==FUNC_DEL){
          //string::size_type firstwhitespace=trunc_line.find_first_of(" ", 0);
          string tok1=tokens[1];
          int functype=(int)strtol(tok1.c_str(), NULL, 10);
          //          cout << "adding function\n";
          vector<double> args;
          int start=(int) strtol(tokens[2].c_str(), NULL, 10);
          for(int i=3; i<tokens.size(); i++){
            args.push_back(strtod(tokens[3].c_str(), NULL));
          }
          if(functype==0){
            Multinomial m(start, args);
            gaps.push_back(&m);
          }         
               else if(functype==1){
               Gaussian g((int) strtod(tokens[2].c_str(), NULL), strtod(tokens[3].c_str(), NULL), (int)strtod(tokens[4].c_str(), NULL), (int)strtod(tokens[5].c_str(), NULL));
           gaps.push_back(&g);
             }
        }
        else if(type==MATRIX_DEL){
          //cout << "matricing\n";
          matricing=true;
        }
        else if(type=="E"){
          //cout << "done sucking in\n";
          done=true;
        }
        //cout << "end of while\n";
     }
     //cout << "finished reading file\n";
     Null n2;
     gaps.push_back(&n2);
     cout << "gap at end is " << gaps[gaps.size()-1]->func(0) << endl;
     readFile.close();
  }
  double scoreSeq(const std::string str){
    return score(pwms.size()-1, gaps.size()-1, str);
  }
        
            
            
  double score(int m, int g, const std::string& str){
   
    cout << "running with motif " << m<< " gap " << g << " str  " << str << endl;
    if(g==0){
      cout << "in last gap"<<endl;
      return 0.0;
    }
    else if(str.length()==0){
      cout << "string ended\n";
      return -10000;
    }
    else{
      if(g==m+1){

      cout <<"in gap mode with gaps " << g << "and no of gaps "<<gaps.size()<<"\n";
      gaps[0]->func(0);
      cout << "finished stupid thing\n";
      cout<<gaps[0]->lowerBound()<<endl;
      int lower=gaps[g]->lowerBound();
      int upper=gaps[g]->upperBound();
      
      double max=-10000;
      double gapvalue=-10000;
      
      cout << " lower upper " << lower << " " << upper << endl;
      for(int i=lower; i<=upper; i++){
        gapvalue=gaps[g]->func(i) + score(m, g-1, str.substr(i, str.length()-1));
        cout << "value at gap "<< i << " " << gapvalue << endl;
        if(gapvalue>max){
            //      cout<< "doing comparison\n";
          max=gapvalue;
        }
      }
      return max;
      
      }else if(g==m){
      
      
      double pwmvalue=-10000;
      pwmvalue=pwms[m].score( str.substr(0, pwms[m].length() ) )
        + this->score( m-1, g, str.substr(pwms[m].length(), str.length()-pwms[m].length()));
      return pwmvalue;
      }
     
     
      /*if(pwmvalue>gapvalue){
        cout<< "went with the pwm\n";
         return pwmvalue;
      }else{
         cout<< "went with the gap\n";
         return gapvalue;
      }  
      
          //cout << gaps[l].func(k)<< endl;
          //cout << pwms[l].score( str.substr(0, pwms[l].length() ) )<< endl;
          return MMotif::max(
                 
          gaps[l].func(k + 1 ) - gaps[l].func(k)+ score(l, k + 1, str.substr(1, str.length()-1)),
          pwms[l].score(str.substr(0, pwms[l].length() ) )
                 
          
          + this->score( l - 1, 0, str.substr(pwms[l].length(), str.length()-pwms[l].length()))
          ); //  max
          
          }*/
    }
     
  }
    double max(double first, double second){
      if(first>=second){
      cout << "returning first arg " << first << endl;
      return first;
    }else{
      cout << "returning second arg " << second << endl;
      return second;
    }
  }
     private:
 

};


produces

gap at end is 0
running with motif 1 gap 2 str  AGCTAAAAGCT
Segmentation fault
Hope you don't mind if I check that tomorrow, but it's about 1am here&now :o)
I am afraid I rather need an answer quickly. I am reposting a question with the new code...feel free to respond.