Reputation: 43
I have a class which is sort of like this:
#include <iostream>
class A {
public:
A (std::istream& is): _is(is) {}
void setInputSource (std::istream& is) {
_is = is;
}
A& operator>> (int& x) {
_is >> x;
return *this;
}
private:
std::istream& _is;
};
And I want the _is
member to act just as a reference. I mean, it has to "point" to an external std::istream
and I don't want the setInputSource()
method to copy the stream that is passed as argument. The problem is that the program won't compile because that method that I mentioned is trying to access the operator=
of the class std::basic_istream<char>
.
My goal is to get the class behave as expected in a program like this:
int main() {
int a, b;
std::ifstream ifs("myfile.txt");
A myA(std::cin);
myA >> a;
myA.setInputSource(ifs);
myA >> b;
return 0;
}
I thought to use pointers instead, but I prefer to use references as I like the fact that they warrantee you that they won't have invalid values and it seems to me that it's a more elegant approach.
Upvotes: 4
Views: 771
Reputation: 96810
Sounds like you just want to change the buffer:
class A
{
public:
A (std::istream& is)
: m_is(is.rdbuf())
{ }
void setInputSource(std::istream& is) {
m_is.rdbuf(is.rdbuf());
}
// ...
private:
std::istream m_is;
};
Upvotes: 1
Reputation: 10064
You can't do this. The only way to define a reference is in the constructor.
It's actually pretty handy because that guarantees that the object will fall out of scope before the reference on which it depends.
For example, with your design, it would be possible to put myA in an invalid state.
int main() {
int a, b;
A myA(std::cin);
myA >> a;
{
std::ifstream ifs("myfile.txt");
myA.setInputSource(ifs);
}
myA >> b;
return 0;
}
You can still shoot yourself in the foot with pointers of course.
Upvotes: 1
Reputation: 110658
You can't bind a reference to a different object after it has already been bound. That's one of the fundamental differences between using pointers and using references. Given this, it would be more appropriate for you to use a pointer.
I prefer to use references as I like the fact that they warrantee you that they won't have invalid values
This isn't true. If the object a reference is bound to is destroyed, then it references an invalid object, just as with pointers.
Upvotes: 4