C++流作为类成员的引用

4

我有一个类,大致上像这样:

#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()方法复制传递的流。问题在于程序无法编译,因为我提到的那个方法正在尝试访问类std::basic_istream<char>operator=
我的目标是使该类在像这样的程序中表现出预期的行为:
int main() {
    int a, b;

    std::ifstream ifs("myfile.txt");
    A myA(std::cin);

    myA >> a;
    myA.setInputSource(ifs);
    myA >> b;

    return 0;
}

我曾考虑使用指针,但我更倾向于使用引用,因为它们可以保证不会有无效值,并且我认为这是一种更加优雅的方法。

3个回答

4

一旦引用绑定了对象,就不能将其绑定到另一个对象。这是使用指针和引用之间的根本差异之一。鉴于此,更适合使用指针。

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

这并不正确。如果引用绑定的对象被销毁,那么它就引用了一个无效的对象,与指针一样。


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

当然,您仍然可以通过指针“自己给脚打枪”。


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

问题在于,我将动态地向下转换为std::ifstream,以检查该类的某些特定方法是否在我的类内的其他方法中,并且仅共享缓冲区不会让我进行这些检查(我认为)。 - skatrak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接