我有一个具有预测数组的安全类 - 预测是一个Class,只保留一个double。 我想允许更改double的值,但只允许正值, 当尝试读取double时,如果值未初始化(在我的代码中等于-1)则抛出异常。 我也有双操作员 这样的事情:
class Prediction{
double value;
public:
.....
Prediction::operator double() const {
return this->prediction;
}
Prediction::operator=(const double value){
...
//check value
}
}
class Security{
...
Prediction& Security::operator[](int index){
return predArray[index];
}
}
Prediction *predArray = new Prediction[4];
//default constructor set the value -1;
double a = predArray[0] //should throw an exception, because predArray[0] = -1
predArray[0] = 4; //should be O.K. because I want to change the value
predArray[1] = -4; //should throw exception, because trying to put negative value;
我在哪里定义阅读和写作,因为我在阅读和写作时做了不同的事情。
感谢
答案 0 :(得分:3)
你不能在operator[]
中这样做。操作员无法知道如何使用它返回的值。因此,您必须根据返回的对象执行此操作。通过抛出返回对象的赋值运算符,您可以很容易地处理负值的赋值。
Prediction::operator=(const double value){
if (value < 0)
throw something;
...
}
如果你想要这句话:
double a = predArray[0];
您必须在转换为双重操作符时执行此操作。
Prediction::operator double() const {
if (value < 0)
throw something;
return value;
}
答案 1 :(得分:1)
使用转换运算符和转换构造函数的组合可以获得此行为。此示例代码应该让您了解如何实现类:
error
ok
error
输出:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.evs.demo.layout.FixedScrollingViewBehavior">
.....
</android.support.v4.widget.NestedScrollView>
答案 2 :(得分:1)
主要思想如下:您可以返回一个带有重载double&
的代理(以及其他必要的代码),而不是返回operator=
。然后,代理执行检查。
struct reference_proxy
{
reference_proxy(double &_d) : d(_d) {}
reference_proxy& operator=(double rhs) //operator= throws when rhs<0
{
if(rhs<0.0)
{
std::cout<<"throw exception"<<std::endl;
}
else
{
std::cout<<"ok"<<std::endl;
d = rhs;
}
return *this;
}
operator double () //cast to double gives an error when uninitialized
{
if(d<0.0)
{
std::cout<<"throw exception"<<std::endl;
}
return d;
}
// add further required functions like operator+= etc.
private:
double& d;
};
然后你可以在其他课程中使用它:
struct Prediction
{
operator double& () { return d; }
double d = -1.0;
};
struct Security
{
template<typename ... Args>
Security(Args&& ... args) : v(std::forward<Args>(args) ...) {}
auto operator[](int i)
{
return reference_proxy(v[i]);
}
std::vector<Prediction> v;
};
应用:
int main()
{
Security s(10);
double a = s[0]; //prints "throw exception"
s[0] = 4; //prints "ok"
s[1] = -4; //prints "throw exception"
return 0;
}
请注意,此方案也可用于更复杂的操作。例如:以观察者模式通知依赖类。
答案 3 :(得分:0)
几点
predArray 数组应该是Security的成员(未在示例代码中显示)
通过[]运算符的索引访问应该在Security的实例上,而不是 predArray 。变量 predArray 是一个原始的对象数组,而不是包含数组的对象。
例如:
Security o = new Security();
double a = o[0] //should throw an exception, because predArray[0] = -1
o[0] = 4; //should be O.K. because I want to change the value
o[1] = -4; //should throw exception, because trying to put negative value;