C ++流引用作为类成员

时间:2014-02-14 16:14:53

标签: c++ stl reference stream

我有一个类似这样的课程:

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

我希望_is成员作为参考。我的意思是,它必须“指向”外部std::istream,我不希望setInputSource()方法复制作为参数传递的流。问题是该程序无法编译,因为我提到的方法是尝试访问类operator=的{​​{1}}。

我的目标是让类在这样的程序中按预期运行:

std::basic_istream<char>

我认为使用指针代替,但我更喜欢使用引用,因为我喜欢他们保证你不会有无效的值,而且在我看来这是一种更优雅的方法。

3 个答案:

答案 0 :(得分:4)

在绑定之后,您无法将引用绑定到其他对象。这是使用指针和使用引用之间的根本区别之一。鉴于此,使用指针更合适。

  

我更喜欢使用引用,因为我喜欢他们保证他们不会有无效值

事实并非如此。如果绑定引用的对象被销毁,那么它引用一个无效对象,就像指针一样。

答案 1 :(得分:1)

你不能这样做。定义引用的唯一方法是在构造函数中。

它实际上非常方便,因为它可以保证对象在它所依赖的引用之前超出范围。

例如,根据您的设计,可以将myA置于无效状态。

int main() {
    int a, b;

    A myA(std::cin);
    myA >> a;

    {
       std::ifstream ifs("myfile.txt");
       myA.setInputSource(ifs);
    }

    myA >> b;

    return 0;
}

当然,你仍然可以用指针射击自己。

答案 2 :(得分:1)

听起来你只想更改缓冲区:

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