考虑对象:
class Obj { public: Obj() : val(new int(1)) {} int& get() {return *val;} const int& get() const {return *val;} private: std::shared_ptr<int> val; };
正如所料,当构造对象并创建副本时,它们都可以通过Obj公开的shared_ptr修改相同的值.
Obj nonconst1; Obj nonconst2(nonconst1); nonconst2.get() = 2; cout << nonconst1.get() << "," << nonconst2.get() << endl;
也可以从非const中复制构造一个const Obj对象,这似乎做了正确的事情,因为它允许读取而不是写入值 – 正如预期的那样,下面的代码会导致编译错误:
const Obj const1(nonconst1); const1.get() = 3;
但是,可以从const one复制构造非const Obj,然后允许修改该值.
Obj nonconst3(const1); nonconst3.get() = 3;
对我来说,这并不觉得是正确的.
有没有办法防止这种行为,同时仍然允许复制构造函数工作?在我的实际用例中,我仍然希望Obd的std容器成为可能.
解决方法
“对我而言,这感觉不是const-correct”但它是:你只是在非const Obj上调用非const get方法.没有错.
如果你真的需要你所追求的行为,你可以使用类似const代理的东西到Obj但是你的客户当然必须能够处理它:
class Obj { //... //original class definition goes here //... friend class ConstObj; }; class ConstObj { public: ConstObj( const Obj& v ) : val( v.val ) {} const int& get() const { return *val; } private: std::shared_ptr<int> val; }; //usage: class WorkingWithObj { public: WorkingWithObj(); Obj DoSomethingYieldingNonConstObj(); ConstObj DoSomethingYieldingConstObj(); }; WorkingWithObj w; Obj nonconst( w.DoSomethingYieldingNonConstObj() ); nonconst.get() = 3; ConstObj veryconst( nonconst ); veryconst.get() = 3; //compiler error ConstObj alsoconst( w.DoSomethingYieldingConstObj() ); alsoconst.get() = 3; //compiler error