2015-12-11 5 views
1

Я пытаюсь перегрузить операторы < < (cout) и >> (cin) на некоторое время для класса сложных чисел, которому мне дали прототипы в a. h файл.перегрузка Извлечение и вставка << >> operator C++

Это моя попытка сделать это в файле class.cpp:

std::istream &operator>> (std::istream &in, complex& c) { 
    double h, j; 
    in >> h >> j; 

    c.set(h,j); 

    return in; 
} 

std::ostream &operator<<(std::ostream &out, complex c) { 
    out << c.getReal; 
    out << c.getImag; 

    return out; 
} 
  1. Это действительно первый раз, когда я видел std:: istream и std:: ostream, а не соиЬ и CIN и я» м на самом деле не знаю, как cout << и cin >> все связаны

  2. Я Протестируйте его на файл main.cpp, но я получаю ошибки

  3. >> должен поглотить сложный аргумент в комплекс класса аргумента и изменить значение частных членов real и imag

  4. Не уверен, если я должен использовать свой набор функций здесь

Это является файлом протипа .h, заполненным мной:

#ifndef COMPLEX_H 
#define COMPLEX_H 


class complex { 

public: 
    complex(); 
    complex(double a); 
    complex(double a, double b); 
    complex(int a, int b); 
    void print() const; 
    void set(double a = 0, double b = 0); 
    void set(int a = 0, int b = 0); 
    double getReal() const; 
    double getImag() const; 
    void get(double&, double&) const; 

    complex operator+ (double& x); 
    complex operator+ (complex&); 
    complex operator+= (complex&); 
    complex operator+= (int&); 
    complex operator++ (int); 
    complex operator++(); 
    complex operator- (double&); 
    complex operator- (complex&); 
    complex operator-= (complex&); 
    complex operator-= (double&); 
    complex operator-- (int); 
    complex operator--(); 
    complex operator* (complex&); 
    complex operator* (double&); 
    complex operator*= (complex&); 
    complex operator*= (double&); 
    complex operator/ (complex&); 
    complex operator/= (complex&); 
    complex operator/= (double); 
    complex operator/ (double); 
    void operator= (const complex&); 
    bool operator== (complex&); 
    bool operator!=(complex &c); 

    friend std::istream &operator>> (std::istream &in, complex& c); 
    friend std::ostream &operator<<(std::ostream &out, complex c); 

    /*complex conj() const; 
    double norm() const; 
    double modulus() const; 
    */ 
private: 
    double real; 
    double imag; 
}; 

#endif // COMPLEX_H 

Может ли кто-нибудь показать мне, как правильно перегрузить это?

Ok, так что я сейчас пытаюсь для вывода а + би:

std::ostream& operator<< (std::ostream& out, complex const& c) { 
    return out << c.getReal() << "+" << c.getImag() << "i"; 
} 

и для ввода:

std::istream& operator>> (std::istream& in, complex& c) { 
    double h, j; 
    if (in >> h >> "+" >> j >> "i") { 
     c.set(h, j); 
    } 
    return in; 
} 

Однако я получаю следующее сообщение об ошибке при компиляции:

Этот для строки 181 моего файла complex.cpp (файл сложной реализации класса), где находится if (in >> h >> "+" >> j >> "i") { указанного выше определения функции:

binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion) 

для всей линии 45 (примечание: каждая ошибка является отдельной, всего 7 для этой строки) моего файла complex.h, где находится friend std::istream &operator>> (std::istream &in, complex& c); protoype.

'istream':is not a member of 'std' 

syntax error missing ';' before '&' 

'istream':'friend' not permitted on data declarations 

missing type specifier-int assumed. Note:C++ does not support default-int 

unexpected token(s) preceding';' 


namespace "std" has no member "istream" 

namespace "std" has no member "istream" 

являются следующие для линии 46 моего файла complex.h где

friend std::ostream &operator<<(std::ostream &out, complex c); 

находится

'ostream': is not a member of 'std' 

syntax error: missing ';' before '&' 

'ostream':'friend' not permitted on data declarations 

missing type specifier -int assumed.Note: C++ does not support default-int 

unexpected token(s) preceding ';' 

namespace "std" has no member "ostream" 

namespace "std" has no member "ostream" 

Я заметил, как тот же самый тип ошибок. Обратите внимание, у меня есть

#include<iostream> 

using namespace std; 

как на файл complex.cpp и файл main.cpp

+0

Кажется разумным, за исключением того, что вам нужно вызвать функции 'get', а не просто назвать их. Измените 'getReal' на' getReal() 'и аналогично' getImag' на 'getImag()' в 'operator <<'. Кроме того, вы подумали о разделении выходных частей? Скажем, с запятой. Кроме этого, вам может быть лучше просить об этом на [CodeReview.SE] (http://codereview.stackexchange.com/) – BoBTFish

+0

Каким образом код не работает? ... и я скажу @BoBTFish, утверждая, что это разумно, несмотря на то, что функция ввода не проверяет свои входы перед использованием! –

+0

Вам необходимо выполнить свои функции ['const' correct] (https://isocpp.org/wiki/faq/const-correctness). – Simple

ответ

6

Давайте начнем с простых вещей: std::cin является экземпляром типа, производного от std::istream.Аналогично, std::cout является экземпляром типа, производного от std::ostream. Эти типы потоков используются, чтобы иметь что-то, что вы можете перегрузить операторы ввода и вывода для (и вы должны не попытаться извлечь из них, чтобы изменить их поведение - это делается с использованием std::streambuf). Существуют и другие типы потоков, например, std::ifstream/std::ofstream (для чтения/записи в файлы) и std::istringstream/std::ostringstream (для чтения/записи в строки).

Следующее, на что нужно обратить внимание, это ваш оператор вывода: для начала вам нужна скобка при вызове функции-члена. Вам также понадобится разделитель между двумя значениями, так как в противном случае реальная и мнимая часть могут смешаться друг с другом. Я бы, наверное, реализовать оператор, как

std::ostream& operator<< (std::ostream& out, complex const& value) { 
    return out << value.getReal() << " " << value.getImag(); 
} 

Использование пространства и никакой другой разделитель может быть неоптимальным в целом, но и делает чтение проще. Для фактической реализации сложного класса я мог бы использовать формат написания реального+емкi или (реального,Imag), но это труднее разобрать.

Чтение значений из потока должно всегда быть проверено после попытки считывания значения. Например, код может выглядеть следующим образом:

std::istream& operator>> (std::istream& in, complex& c) { 
    double h, j; 
    if (in >> h >> j) { 
     c.set(h, j); 
    } 
    return in; 
} 

за исключением недостающее проверки функция входа выглядит нормально при условии, что два значения разделяются пробелом: перед тем, как прочитать значение, пространство пропускаются по умолчанию с операторы ввода. Если значения отформатированы больше, чем некоторые разделители, их нужно будет обрабатывать отдельно. Код для этого может выглядеть следующим образом:

template <char C> 
std::istream& skip_char(std::istream& in) { 
    if ((in >> std::skipws).peek() != C) { 
     in.setstate(std::ios_base::failbit); 
    } 
    else { 
     in.ignore(); 
    } 
    return in; 
} 
std::istream& (*const open_parenthesis)(std::istream&) = &skip_char<'('>; 
std::istream& (*const close_parenthesis)(std::istream&) = &skip_char<')'>; 
std::istream& (*const comma)(std::istream&) = &skip_char<','>; 

std::istream& operator<< (std::istream& in, complex& c) { 
    double real, imag; 
    if (in >> open_parenthesis >> real >> comma >> imag >> close_parenthesis) { 
     c.set(real, imag); 
    } 
    return in; 
} 

Эти забавные выглядящие существа open_parenthesis, close_parenthesis и comma являются указатели на функции инициализированы, чтобы указать экземпляр шаблона функции skip_char. У них есть специальная подпись, которая квалифицирует их как манипуляторы. Когда «считывание» в «манипулятор», соответствующая функция вызывается с потоком, из которого они «считываются». То есть, например, std::cin >> comma приводит к вызову comma(std::cin), что на самом деле является вызовом skip_char<','>(std::cin). Однако, я думаю, для этого задания полномасштабный подход немного переборщит.

+0

damn, Да, мне нужно сделать это в форме a + bi, я понимаю, как синтаксис лучше работает, но я все равно получаю ошибки (я расскажу им в обновленном вопросе) только из тех двух функций друзей, которые aren В противном случае, когда я их прокомментирую, я опубликую обновленную версию этого вопроса, так как я предполагаю, что это неправильное место, так как я не могу опубликовать код в комментарии: p – GustX

+0

Или я мог бы просто отредактируйте это – GustX

Смежные вопросы