C++ 从流创建具有常量参数的对象

C++ 从流创建具有常量参数的对象,c++,C++,让我们假设我有一个 #include <iostream> using namespace std; class Test{ public: friend istream& operator >> (istream& input, Test& test){ input >> test.dummy; return input; };

让我们假设我有一个

#include <iostream>
using namespace std;

class Test{
    public:
        friend istream& operator >> (istream& input, Test& test){
            input >> test.dummy;
            return input;
        };
        friend ostream& operator << (ostream& output, Test& test){
            output << test.dummy << endl;
            return output;
        };
    private:
        const int dummy;
}
#包括
使用名称空间std;
课堂测试{
公众:
friend istream&operator>>(istream&输入、测试和测试){
输入>>test.dummy;
返回输入;
};

friend ostream&operator你不能。流是你从中读取的东西,它们不是工厂或类似的东西

不过,您有几种选择:

  • 从流中读取非
    常量
    ,然后使用它初始化
    常量
    对象

  • 您可以将
    设为非
    常量
    ,将对象初始化为未读,然后读入
    ;然后您可以仅将外部
    常量&
    传递到


定义一个
虚拟
类:

class Dummy {
public:
    Dummy() { value = 0; }
    friend istream& operator >> (istream& input, const Dummy& dummy){
        input >> dummy.value;
        return input;
    }
    friend ostream& operator << (ostream& output, const Dummy& dummy){
        output << dummy.value << endl;
        return output;
    }
    int getValue() const { return value; }
private:
    mutable int value;
};
“我真的,真的需要这个”的方式 使用const_cast。通常情况下,您将其用于外部看起来像常量的对象,但内部确实需要时不时地更新状态。至少可以说,将其用于从流读取有点混乱

friend istream& operator >> (istream& input, Test& test){
    input >> const_cast<int&>(test.dummy);
    return input;
};
最好的办法
丢弃常量。相反,如果需要,将整个对象作为常量传递。

您声明了
dummy
const
,因此显然,在
测试的生命周期内对其进行变异将打破关于
常量的约定

这就是
operator>>
目前正在做的事情,编译器正在帮助您防止违反该合同

操作员>>
是否实际执行了
测试的初始化?
如果
操作员>>
只执行
测试的初始化,而不覆盖
测试
,则应将
操作员>>
转换为出厂功能,如Gwiazdorr的“推荐方式”所示

另一方面,如果
操作符>
应该覆盖
测试
,那么你就违反了关于
常量的约定,这是很糟糕的。因此,
应该是非
常量

dummy
真的需要是
const

您可以通过
Test
的接口简单地强制执行
dummy
的不变性。尽管在这种情况下,它仍然可能在类内部发生变异,这可能是您试图避免的。

可能是删除上一个对象。创建另一个对象并使上一个对象指向它。ostream操作符不应既然你没有改变里面的测试类,那就做一个
测试常量&
。你能解释一下为什么
虚拟
常量
以及你在代码中使用
操作符>
做什么吗?@user673679我明白了,我没有说清楚,请看编辑。我明白mutable在这里起了作用。这也是一个有效的poss第二个建议是可怕的。“BartekBanachewicz为什么?因为在无效状态下构造对象是一个常见的问题来源,违背了现代C++最佳实践。@ BartekBanachewicz,你说得对,但我没有说过无效;我是指“沿着代码> BooReal[ft=;false;
:”]从OP代码中,我不知道。如何使用
Test
。读取时,Test可能会向另一个线程发送信号,或者发送消息,或者只是更改其内部状态。不过,我必须承认我不是很清楚,所以欢迎使用-1
friend istream& operator >> (istream& input, Test& test){
    input >> const_cast<int&>(test.dummy);
    return input;
};
static Test fromStream(istream& input) {
    int dummy;
    input >> dummy;
    return Test(dummy);
}