tags:

views:

527

answers:

4

I'm currently trying to initialise a private istream variable in class. The class definition looks like:

    #define PARSER_H

class parser {
  public:
    parser();
    parser(string predict_table_file_name);
 private:
    int getMaxRHS(string predict_table_file_name);
    int getMaxPairs(string predict_table_file_name);
    int getMaxPairsY(string predict_table_file_name);
    int getMaxRHSY(string predict_table_file_name);
    int getMaxSymbols(string predict_table_file_name);
    int getGoalSymbol(string predict_table_file_name);
    int getNumberOfTerminalSymbols(string predict_table_file_name);
    string getSymbol(int symbolID);
    string getToken();
    string openFile(string sourceFile);
    bool isTerminalSymbol(string token, string symbolArray[], int terminalSymbols);
    istream scanFile;
};

#endif

The variable in question is "istream scanFile". The code I'm using to try and initialize it looks like this.

string parser::openFile(string sourceFile) {
  filebuf fb;
  fb.open(sourceFile.c_str(), ios::in);
  parser::scanFile(&fb);
}

The line "parser::scanFile(&fb);" is giving me the trouble. Apparently the compiler thinks I'm trying to call function, which I guess I am, but I just want to call the constructor on parser::scanFile.

I'm new-ish to C++, so any help would be greatly appreciated.

A: 

You want something like:

   parser::scanFile = istream(&fb);

to invoke the constructor.

Doug T.
Unfortunately that won't work. `istream` does not have a default constructor, so you must initialize it in the constructor initialization list - you cannot initialize it by assignment.
hrnt
Even if `scanFile` was properly constructed, that wouldn't work, because `istream` does not have `operator=` defined.
hrnt
A: 

You must do such initialization in the initialization list of the constructor. Why do you want to implement openFile as a separate function?

Also, if scanFile is used for reading from files, why not use ifstream instead?

Are you going to create parsers that are not associated with files? If not, try this for the constructor:

parser(string sourceFile) : scanFile(sourceFile.c_str()) { ... other constructor stuff ... }

That assumes that scanFile is a ifstream. Using a istream is more complex. Your original code would not have worked, because the filebuf is destroyed when you exit the openFile function.

hrnt
A: 

You can't, because the object is already constructed. But you can

scanFile.rdbuf( &fb );

but that won't do either, because fb will be destructed as soon as you return from the openFile. But you'll have to resolve this problem yourself, because it's your code flow.

Michael Krelin - hacker
+1  A: 

To solve your question you can add the filebuf as a member variable.

class parser
{
    // STUFF LIKE BEFORE
    filebuf fb;
    istream scanFile;
};

parser::parser()
    :fb()
    ,scanFile(&fb)
{}

string parser::openFile(string sourceFile)
{
    fb.open(sourceFile.c_str(), ios::in);
}

But you should probably be using an fstream object:

class parser
{
    // STUFF LIKE BEFORE
    ifstream scanFile;
};

parser::parser()
    :scanFile()
{}

string parser::openFile(string sourceFile)
{
    scanFile.open(sourceFile.c_str());
}

see: http://www.cplusplus.com/reference/iostream/fstream/

Martin York