Reputation: 1209
I am still wondering about istream operator>>.
In my function istream& operator >> (istream &is, Student& a)
, I didn't use is
but still return it at the end of the function. I still get the correct answer with cin >> a
. Can anyone explain why?
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student() : age(0){}
Student (int age1) : age(age1) {}
void setAge();
int getAge(){return age;}
friend istream& operator >> (istream& is, Student& a);
};
istream& operator >> (istream &is, Student& a)
{
a.setAge();
return is;
}
void Student::setAge(){
int age1;
cout << "input age of the student: "<< endl;
cin >> age1;
age = age1;
}
int main()
{
Student a;
cin >> a;
cout << "Age of Student is " << a.getAge() << "?";
}
Upvotes: 1
Views: 1238
Reputation: 385264
I didn't use
is
Yes you did. You just used it from a different function, is all.
It's the same stream because it's cin
in both cases.
If you ever wanted to extract from a different stream then your code would be broken. This is why we prefer to use the argument to operator>>
rather than sort of guessing at what it was (cin
).
Upvotes: 0
Reputation: 930
Actually there are quite a few points to make in your example.
Firstly a setter should have a parameter. By convention, a setter always gets a parameter which alters the class and then the getter is parameterless and should be const.
Secondly, your implementation of setAge directly accesses std::cin. If you look at my example you will see that I do make use of the is parameter. That separates the setAge from the source of the parameter and allows for better OOD.
Thirdly, my implementation also provides better abstraction because the input stream is could be any stream (for example a file, or maybe a stream from the internet)
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student() : age(0){}
Student(int age1) : age(age1) {}
void setAge(int age1);
int getAge() const { return age; }
friend istream& operator >> (istream& is, Student& a);
};
istream& operator >> (istream &is, Student& a)
{
int age1;
is >> age1;
a.setAge(age1);
return is;
}
void Student::setAge(int age1){
age = age1;
}
int main(int argc, char* argv[])
{
Student a;
cout << "input age of the student: " << endl;
cin >> a;
cout << "Age of Student is " << a.getAge() << "?" << endl;
return 0;
}
Upvotes: 0
Reputation: 597036
In my function
istream& operator >> (istream &is, Student& a)
, I didn't useis
but still return it at the end of the function. I still get the correct answer withcin >> a
. Can anyone explain why?
Because Student::setAge()
is accessing cin
directly, which is the same stream that is
happens to be pointing at in your example.
This is not the correct design. A member setter should not be prompting the user for input. You should prompt for input first, then pass the value to your setter afterwards. The class should be agnostic about where its values are coming from.
Use something more like this instead:
#include <iostream>
using namespace std;
class Student
{
private:
int age;
public:
Student() : age(0){}
Student (int age1) : age(age1) {}
void setAge(int value);
int getAge(){return age;}
void readFrom(istream& is);
};
istream& operator >> (istream &is, Student& a)
{
a.readFrom(is);
return is;
}
void Student::readFrom(istream& is){
is >> age;
}
void Student::setAge(int value){
age = value;
}
int main()
{
Student a;
int age;
cout << "input age of the student: "<< endl;
cin >> age;
a.setAge(age);
cout << "Age of Student is " << a.getAge() << "?";
}
Upvotes: 2
Reputation: 14039
This works fine because you are calling
cin >> a;
If instead you did this
ifstream ifs ("test.txt", ifstream::in);
ifs >> a;
Then your program will read from standard input instead of the file (test.txt) like it's supposed to be doing.
The correct implementation would be
istream& operator >> (istream &is, Student& a)
{
return is >> a.age;
}
Now if you call
cin >> a;
it would read from standard input
and if you call
ifs >> a;
it would read from the file.
Upvotes: 5