我怎样才能创建一个有时只读,有时可写的课程?一个选项是使用getter / setter和一个标志来指示对象是否是只读的,但这是一个很大的开销。我还希望这个readonly属性能够深入研究对象,确保它包含的所有对象都是readonly或writeable。这是我尝试但未能使用const实现的所需行为的一些示例代码。
这个问题非常通用,所以之前可能已经提出过,但我无法在stackoverflow上找到这个确切问题的良好解决方案。
示例代码: https://ideone.com/4cXyNF
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
class OuterClass {
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int i_;
InnerClass& reference_;
InnerClass* pointer_;
};
int main() {
InnerClass c(1);
OuterClass readwrite(2, c);
// Desire these 3 operations to work on the writable object
readwrite.i_ = 3;
readwrite.reference_.j_ = 4;
readwrite.pointer_->j_ = 5;
const OuterClass readonly(6, c);
// COMPILER ERROR: error: assignment of member 'OuterClass::i_'
// in read-only object
// readonly.i_ = 7;
// Desire this to be a compiler error, but it isn't
readonly.reference_.j_ = 8;
// Desire this to be a compiler error, but it isn't
readonly.pointer_->j_ = 9;
return 0;
}
答案 0 :(得分:2)
如果将成员更改为函数,则可以创建此方法的常量重载
class InnerClass {
public:
explicit
InnerClass(int j) : j_(j) {}
int& j() { return j_; }
const int& j() const { return j_; }
private:
int j_;
};
class OuterClass {
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int& i() { return i_; }
const int& i() const { return i_; }
InnerClass const& reference() const { return reference_; };
InnerClass & reference() { return reference_; };
InnerClass const* pointer() const { return pointer_; };
InnerClass * pointer() { return pointer_; };
private:
int i_;
InnerClass& reference_;
InnerClass* pointer_;
};
int main() {
InnerClass c(1);
OuterClass readwrite(2, c);
// Desire these 3 operations to work on the writable object
readwrite.i() = 3;
readwrite.reference().j() = 4;
readwrite.pointer()->j() = 5;
const OuterClass readonly(6, c);
// COMPILER ERROR: error: assignment of member 'OuterClass::i_'
// in read-only object
readonly.i_ = 7;
// Desire this to be a compiler error, and it is
readonly.reference().j() = 8;
// Desire this to be a compiler error, and it is
readonly.pointer()->j() = 9;
return 0;
}
<强> Live on Coliru 强>
答案 1 :(得分:2)
如果对象本身是const
,您可以通过使用成员函数返回引用/指针const
来实现此目的。
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
class OuterClass
{
InnerClass& reference_;
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c) {}
int i_;
InnerClass & in() { return reference_; }
InnerClass const & in() const { return reference_; }
};
如果i_
为in().j_
,outer
和const
都不可写:
InnerClass i{ 1 };
OuterClass write(2, i);
write.i_ = 3; // works
write.in().j_ = 3; // works
OuterClass const read(2, i);
read.i_ = 3; // error!
read.in().j_ = 3; // error!
答案 2 :(得分:1)
这是与其他已经发布的类似的解决方案,但采用了稍微不同的方法:
class InnerClass {
public:
InnerClass(int j) : j_(j) {}
int j_;
};
template<bool readOnly>
class OuterClass{
public:
OuterClass(int i, InnerClass& c) : i_(i), reference_(c), pointer_(&c) {}
int i_;
typename std::conditional<readOnly,const InnerClass&, InnerClass&>::type reference_;
typename std::conditional<readOnly,const InnerClass* const, InnerClass*>::type pointer_;
};
int main(int argc,char** args){
InnerClass c(1);
OuterClass<true> readonly(12,c);
//readonly.reference_.j_ = 1; //Error "reference_ is read only"
//readonly.pointer_->j_ = 1; //Error "pointer_ is read only"
OuterClass<false> write(12,c);
write.reference_.j_ = 1;
write.pointer_->j_ = 1;
}