C++ C++;隐式类型转换

C++ C++;隐式类型转换,c++,type-conversion,operator-keyword,C++,Type Conversion,Operator Keyword,我想将许多相似的类相互转换。它们至少有一个共同的抽象祖先,它定义了两个基本方法 我遇到了奇怪的打字错误,所以我做了一个简单的例子。在层次结构的顶部:Integer类。它是一个具有int val()方法的抽象类。它的一个子元素只是物理int值的持有者,而另一个子元素引用2个整数,val()是它引用的两个整数的总和 我写了这段代码,我不明白为什么注释表达式在使用临时变量时无法编译 class Sum; class Integer { public: virtual int

我想将许多相似的类相互转换。它们至少有一个共同的抽象祖先,它定义了两个基本方法

我遇到了奇怪的打字错误,所以我做了一个简单的例子。在层次结构的顶部:Integer类。它是一个具有
int val()
方法的抽象类。它的一个子元素只是物理
int
值的持有者,而另一个子元素引用2个整数,
val()
是它引用的两个整数的总和

我写了这段代码,我不明白为什么注释表达式在使用临时变量时无法编译

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;
}
类和;
类整数{
公众:
虚拟int val(void)const=0;
求和运算符+(整数和其他);
};
类和:公共整数{
私人:
整数&op1和&op2;
公众:
显式和(整数&a,整数&b):op1(a),op2(b){};
int val(void)const{return op1.val()+op2.val();};
};
类Int:公共整数{
私人:
INTV;
公众:
Int(Int-value=0):v(value){};
Int(Integer&other):v(other.val()){};
int val()常量{return v;};
Int&operator=(Integer&other){v=other.val();返回*this;};
Int&operator=(Int-value){v=value;返回*this;};
};

std::ostream&operator对于采用非常量引用的函数,如Int的构造函数,不能传递临时对象。对此的一种常见解释是,如果函数采用非常量引用,则允许修改referent,但对于临时对象,这种更改实际上不会发生,因为referent变量在函数调用之外是不可访问的


正如DyP在评论中所建议的那样,将值更改为const将提供一个解决方案,或者您可以简单地将其绑定到一个变量,就像您对'Sum r=a+b'所做的那样。

对于采用非const引用的函数,如Int的构造函数,您不能传递临时对象。对此的一种常见解释是,如果函数采用非常量引用,则允许修改referent,但对于临时对象,这种更改实际上不会发生,因为referent变量在函数调用之外是不可访问的

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;};
};
正如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;
运算符+
(可以说它应该是一个自由函数而不是成员函数)返回类型为
Sum
的prvalue/temporary。此临时变量无法绑定到非常量左值引用,因此无法使用构造函数
Int(Integer&other)

类似地,对于
Int&operator=(Integer&other)
,常量引用就足够了

构造函数
Int(Integer&other)
不修改其参数,因此可以(应该)进行引用
const

Int(Integer const& other) : v(other.val()) {};
这也解决了您的问题:

Sum Integer::operator+(Integer & other);
Int s = a+b;
运算符+
(可以说它应该是一个自由函数而不是成员函数)返回类型为
Sum
的prvalue/temporary。此临时变量无法绑定到非常量左值引用,因此无法使用构造函数
Int(Integer&other)


类似地,对于
Int&operator=(Integer&other)
,常量引用就足够了。

Int(Integer&other)
这应该是
Int(Integer-const&other)
。一旦我更改了它,使用名称空间std添加一个
#include
和一个
,并将变量名更改为
s2
,它工作正常。似乎有效。谢谢
Int(Integer和other)
这可能应该是
Int(Integer const和other)
。一旦我更改了它,就添加一个
#include
和一个
使用名称空间std
,并将变量名更改为
s2
,它工作正常。似乎有效。谢谢!当您说
操作符+
应该是非成员函数时;主要原因是什么?@Titou 1)它可以作为一个自由函数实现。2) 也允许转换第一个参数。3) 对称性。4) 当您说
操作符+
应该是非成员函数时,请参见项目符号7;主要原因是什么?@Titou 1)它可以作为一个自由函数实现。2) 也允许转换第一个参数。3) 对称性。4) 见项目7