Проблема с именованным конструктором с аргументом istream - PullRequest
1 голос
/ 08 февраля 2010

Я пытаюсь создать именованный конструктор для моего класса Matrix с входом в качестве потока, из которого я могу прочитать значения для инициализации.

#include <istream>
// ...

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

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

Метод должен быть реализован более или менее так

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;
}

Однако при компиляции я получаю сообщение об ошибке в объявлении метода (строка 74 - это место, где определен прототип, и 107, где начинается реализация)

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

Эти ошибки, однако, я не получаю при определении и реализации именованного конструктора с простым параметром, например, int.

Что мне не хватает? Любая помощь будет принята с благодарностью.

1 Ответ

6 голосов
/ 08 февраля 2010

istream находится в пространстве имен std:

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

Ошибка указывает на то, что она потеряна, когда достигнет istream. Измените это и в заголовке и в источнике, конечно. Пара замечаний:

В заголовке используйте <iosfwd> вместо <istream>, а в исходном файле - <istream>. Это более «правильно» и может ускорить компиляцию.

Кроме того, вы действительно хотите вернуть вновь выделенную память? Это рискованно и не очень безопасно. Распределение стека будет намного проще, а может быть, даже быстрее.

Наконец, просто кое-что, что нужно иметь в виду: вы очень близки к тому, чтобы иметь хороший operator<<. Вы можете реализовать его с точки зрения текущей функции:

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

    pResult = Matrix::from_stream(pStream);

    // ... more book keeping
}
...