【问题标题】:C++ stream reference as class memberC++ 流引用作为类成员
【发布时间】:2014-02-14 16:14:53
【问题描述】:

我有一门课是这样的:

#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&lt;char&gt; 类的 operator=

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

int main() {
    int a, b;

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

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

    return 0;
}

我想改用指针,但我更喜欢使用引用,因为我喜欢这样一个事实,即它们向您保证它们不会有无效值,而且在我看来这是一种更优雅的方法。

【问题讨论】:

    标签: c++ stl reference stream


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      int main() {
          int a, b;
      
          A myA(std::cin);
          myA >> a;
      
          {
             std::ifstream ifs("myfile.txt");
             myA.setInputSource(ifs);
          }
      
          myA >> b;
      
          return 0;
      }
      

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

      【讨论】:

        【解决方案3】:

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

        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 以检查该类的某些特定方法在我的类中的其他方法中,并且仅共享缓冲区不会让我这样做那种抱怨(我认为)。
        猜你喜欢
        • 2013-03-08
        • 2013-01-10
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        相关资源
        最近更新 更多