[英]C++ implicit typecast
我想将许多相似的类相互转换。 他们至少有一个共同的抽象祖先,它定义了2种基本方法。
我遇到了奇怪的类型转换错误,因此我举了一个简化的例子。 在层次结构的顶部:Integer类。 这是一个具有int val()
方法的抽象类。 它的一个孩子只是物理int
值的持有者,而另一个引用2个Integers,而val()
是两个引用的Integer的总和。
我写了这段代码,但我想不出为什么使用临时变量时注释表达式无法编译的原因。
class Sum;
class Integer {
public:
virtual int val(void) const = 0;
Sum operator+(Integer & other);
};
class Sum : public Integer {
private:
Integer &op1, &op2;
public:
explicit Sum(Integer &a, Integer &b) : op1(a), op2(b) {};
int val(void) const {return op1.val() + op2.val();};
};
class Int : public Integer {
private:
int v;
public:
Int(int value=0) : v(value) {};
Int(Integer & other) : v(other.val()) {};
int val() const {return v;};
Int & operator=(Integer & other){v = other.val(); return *this;};
Int & operator=(int value){v = value; return *this;};
};
std::ostream & operator<<(std::ostream & out, Integer & i){return out << i.val();}
Sum Integer::operator+(Integer & other){return Sum(*this, other);}
int main(int argc, const char **argv){
Int a=42, b=57;
// Int s = a+b; => conversion from ‘Sum’ to non-scalar type ‘Int’ requested
Sum r = a+b;
Int s = r; /* OK */
cout << a << " + " << b << " = " << s << endl;
return 0;
}
对于采用非const引用的函数,例如Int的构造函数,您不能传递临时对象。 对此的一种常见解释是,如果您的函数采用非const引用,则可以修改引用,但对于临时对象,由于无法从外部访问引用变量,因此此更改不会真正起作用。函数调用。
正如DyP在注释中建议的那样,将值更改为const将提供解决方案,或者您可以像将其与'Sum r = a + b'一样简单地将其绑定到变量。
class Int : public Integer {
private:
int v;
public:
Int(int value=0) : v(value) {};
Int(Integer & other) : v(other.val()) {};
int val() const {return v;};
Int & operator=(Integer & other){v = other.val(); return *this;};
Int & operator=(int value){v = value; return *this;};
};
构造函数Int(Integer & other)
不会修改其参数,因此可以(应该)使该引用成为const
:
Int(Integer const& other) : v(other.val()) {};
这也解决了您的问题:
Sum Integer::operator+(Integer & other);
Int s = a+b;
operator +
(可以说是一个自由函数,而不是成员函数)返回Sum
类型的prvalue / temporary。 此临时不能绑定到非常量左值引用,因此不能使用构造函数Int(Integer & other)
。
类似地,对于Int & operator=(Integer & other)
,const引用就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.