Creating object with constant parameters from stream

前端 未结 4 2056
我在风中等你
我在风中等你 2021-01-18 05:02

let us assume I have a class with

#include 
using namespace std;

class Test{
    public:
        friend istream& operator >> (istr         


        
相关标签:
4条回答
  • 2021-01-18 05:41

    Define a Dummy class:

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

    And use it in Test:

    class Test {
    public:
        Test() { cin >> dummy; }
    private:
        const Dummy dummy;
    };
    

    It works as expected.

    0 讨论(0)
  • 2021-01-18 05:54

    The "I really, really need this" way

    Use const_cast. Usually you use it for objects that outside look like if they are constant, but internally they do need to update state every now and then. Using it for reading from stream is a little confusing, to say the least.

    friend istream& operator >> (istream& input, Test& test){
        input >> const_cast<int&>(test.dummy);
        return input;
    };
    

    The recommended way

    Ditch stream operator, use a factory function.

    static Test fromStream(istream& input) {
        int dummy;
        input >> dummy;
        return Test(dummy);
    }
    

    The best way

    Ditch const. Instead, pass your entire object as const if needed.

    0 讨论(0)
  • 2021-01-18 05:55

    You declared dummy const, so obviously mutating it during the lifetime of Test would break the contract about const.

    This is what operator>> is doing at the moment and the compiler is helpfully trying to prevent you from breaking that contract.

    Does operator>> actually do the initialization of Test?

    If operator>> should only do the initialization, not overwriting, of Test, then you should turn operator>> into a factory function, as demonstrated in gwiazdorrr's "recommended way".

    If, on the other hand, operator>> should overwrite Test, then you're breaking the contract about the constness of dummy, and that's just bad. Therefore, dummy should be non-const.

    Does dummy really need to be const?

    You could simply enforce the immutability of dummy through the interface of Test. Though in this case it could still be mutated inside the class, which is probably what you're trying to avoid.

    0 讨论(0)
  • 2021-01-18 06:03

    You can't. Streams are something you read from, they are not factories or something like that.

    You have several choices, though:

    • Read from the stream to a non-const, and then use that to initialize your const object

    • You can make dummy non-const, initialize your object as unread, and then read into dummy; then you can pass outside only const& to dummy

    0 讨论(0)
提交回复
热议问题