views:

78

answers:

1

Hi,

I'm trying to create a named constructor for my class Matrix, with an input as a stream from which I can read the values for the initialization.

#include <istream>
// ...

class Matrix
{
public:
    Matrix(int);
    // some methods
    static Matrix *newFromStream(istream&);

private:
    int n;
    std::valarray< Cell > data;
};

The method should be implemented more or less like this

Matrix *Matrix::newFromStream(istream &ist) {

    // read first line and determine how many numbers there are
    string s;
    getline( ist, s );
    ...
    istringstream iss( s, istringstream::in);

    int n = 0, k = 0;
    while ( iss >> k)
        n++;
    Matrix *m = new Matrix( n );    

    // read some more values from ist and initialize        

    return m;
}

However, while compiling, I get an error in the declaration of the method (line 74 is where the prototype is defined, and 107 where the implementation starts)

hitori.h:74: error: expected ‘;’ before ‘(’ token
hitori.cpp:107: error: no ‘Matrix* Matrix::newFromStream(std::istream&)’ member function declared in class ‘Matrix’

These errors, however, I do not get when defining and implementing a named constructor with a simple parameter, like an int.

What am I missing? Any help would be greatly appreciated.

+6  A: 

istream is in the namespace std:

static Matrix *newFromStream(std::istream&);

The error indicates it's lost once it gets to istream. Change it in both header and source, of course. A couple notes:

In your header, use <iosfwd> instead of <istream>, and in your source file use <istream>. This is more "correct" and may speed up compilation.

Also, do you really want to return newly allocated memory? This is risky and isn't terribly safe. Stack-allocation would be much easier, and maybe even faster.

Lastly, just something to keep in mind: You're very close to having a good operator<<. You can implement it in terms of your current function:

std::istream& operator<<(std::istream& pStream, Matrix& pResult)
{
    // ... book keeping for istream

    pResult = Matrix::from_stream(pStream);

    // ... more book keeping
}
GMan
and similarly use `std::istream` in the implementation.
quamrana
@quamrana: Usually assumed I think, but I'll add.
GMan
Thanks, that was it!And yes, an >>operator should probably be more appropriate.Regarding the memory, I only know the size of Matrix when I read the first line from the stream.Do you mean I should do something likeMatrix m();cin >> m;and that I have some kind of resize method inside 'from_stream'?
mvaz
@mvaz: I mean make the return value `Matrix` instead of `Matrix*`, and change `while ( iss >> k) n++; Matrix *m = new Matrix( n );` to `while ( iss >> k) n++; Matrix m( n );`.
GMan