2012-01-15 3 views
3

Можно создать дубликат:
Operator overloadingперегружать оператор извлечения >> в C++

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

clockType.h

#include<iostream> 
using namespace std; 

class clockType 
{ 
public: 
    clockType(); 
    void getTime(); 
    friend istream& operator>>(istream&, const clockType); 
private: 
    int hr, min, sec; 
} 

clockType.cpp

#include<iostream> 
#include'clockType.h" 
using namespace std; 

clockType::clockType() 
{ 
    hr = 0; 
    min = 0; 
    sec = 0; 
} 

void clockType::getTime() 
{ 
    while(hr>=24) 
     hr = hr - 24; 
    while(min>=60) 
     min = min - 60; 
    while(sec>=60) 
     sec = sec - 60; 
    cout<<setfill('0') 
     <<setw(2)<<hr<<":" 
     <<setw(2)<<min<<":" 
     <<setw(2)<<sec<<endl; 
} 

istream& operator>>(istream& in, clockType cl) 
{ 
    in>>cl.hr>>cl.min>>cl.sec; 
    return in; 
} 

entryPoint.cpp

#include<iostream> 
#include'clockType.h' 

using namespace std; 

int main() 
{ 
    clockType clock; 
    cout<<"Enter hr, min, sec"; 
    cin>>clock; 
    clock.getTime(); 
    return 0; 
} 

Там нет ошибки. Мой вопрос: когда я вхожу в час, мин и сек, почему он выводит 00:00:00? Почему не передают свои значения объектным часам?

+2

Вы должны ** никогда не использовать операции ввода-вывода без проверки ошибок. Любая из ваших операций может выйти из строя на любом этапе, и вы никогда не должны предполагать, что ваши переменные имеют значимые значения, если все операции не удастся. В частности, вы не должны перезаписывать свои живые переменные, пока не убедитесь, что прочитали действительный ввод. –

+0

Недавно я провел курс C++, который содержал эту точную проблему. Если это домашняя работа, не забудьте обозначить ее как таковую. – Bingo

ответ

5

Сигнатура operator>> потребности быть

istream& operator>>(istream& in, clockType& cl) 

То есть, он должен принять ссылку к clockType инстанции.

Ваш текущий код принимает экземпляр clockType, поэтому при вызове оператора создается временная копия вашего clock, и оператор работает над этим. Затем копия отбрасывается, а ваш исходный код clock остается неизменным.

Еще одна проблема заключается в том, что вы не проверяете, успешно ли вы прочитали что-либо из вашего входного потока. Любые и все операции >> на in могут потерпеть неудачу, что может оставить cl в неизвестном состоянии. Поэтому прежде всего вам следует проверить успех с чем-то вроде if(in >> cl.hr).

Этого еще недостаточно, потому что первая операция чтения (в hr) может быть успешной, но следующая может потерпеть неудачу; что оставит cl в неизвестном состоянии. Было бы хорошо, если бы оператор извлечения имел семантику транзакции, то есть либо он обновлял все три члена, либо иным образом оставляет объект в своем предыдущем состоянии. Один из способов сделать это - сначала прочитать локальные переменные, и только если все три чтения будут скопировать значения в cl.

+0

Ну, я сделал это, но эта ошибка появляется: ошибка C2248: 'clockType :: hr': не может получить доступ к закрытому члену, объявленному в классе 'clockType' То же самое касается мин и сек .. – Julienn

+2

@JulienNicolas: Вам также нужно обновите декларацию 'friend' внутри' class clockType', чтобы соответствовать сигнатуре оператора - это само собой разумеется. – Jon

2
istream& operator>>(istream& in, clockType cl) 

должно быть:

istream& operator>>(istream& in, clockType &cl) // (note the &) 
3

Ваш оператор добычи, вероятно, следует изменить объект, переданный ему, а не только копии.То есть, вы хотите, чтобы сделать второй аргумент вашего оператора экстракционного неконстантным эталонным тоже:

std::istream& operator>> (std::istream& in, clockType& cl) { ... } 

КСТАТИ всегда проверить, что добыча работала перед использованием результатов:

if (std::cin >> clock) { ... } 
1

Вы должны взять объект clockType в свой operator>> по ссылке, иначе он будет считывать только локальный объект функции.

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