问题描述
我有2个基类(带有复制构造函数)和派生类,在基类伊中有重载的operator+
:
I have 2 classes, base (with copy constructor) and derived, in base Ι have overloaded operator+
:
class Base {
public:
Base(const Base& x) {
// some code for copying
}
Base operator+(const Base &bignum) const {
Base x;
/* ... */
return x;
}
};
class Derived : public Base {
};
当我尝试做类似的事情
Derived x;
Derived y;
Derived c=x+y;
我收到错误:conversion from "Base" to non-scalar type "Derived" derived
问题可能出在那个操作符+返回Base
类型的对象,而我想将其分配给Derived
类型的对象吗?
I get error: conversion from "Base" to non-scalar type "Derived" derived
Could problem be in that operator + returns object of Base
type and I want assign it to Derived
type object?
推荐答案
实际上,您不需要重新定义operator+
(除非您的设计需要它,如Ajay的示例所指出).
In fact you don't need to redefine the operator+
(unless your design requires it, as Ajay's example pointed out).
以下面的简单示例为例:
Take the following minimalistic example:
struct Base {
Base operator+ (Base a) const
{ cout <<"Base+Base\n"; }
Base& operator= (Base a)
{ cout<<"Base=Base\n"; }
};
struct Derived : public Base { };
int main() {
Base a,b,c;
c=a+b; // prints out "Base+Base" and "Base=Base"
Derived e,f,g;
e+f; // prints out "Base+Base" (implicit conversion);
}
这是完美的,因为遇到e+f
时,编译器会找到基类的operator+
,他隐式地将Derived
转换为Base
,并计算出类型为Base
的结果.您可以轻松编写c=e+f
.
This works perfectly, because when encountering e+f
the compiler finds operator+
of the base class, and he implicitly convert from Derived
to Base
, and computes a result which is of type Base
. You could easily write c=e+f
.
问题仅从辅助派生开始.一旦尝试g=e+f;
,您将得到一个错误.编译器不确定是否将A放入B.这种谨慎性是由常识证明的:所有猿类都是动物,但并非所有动物都一定是猿.
The problem starts only with the assigment to a Derived. As soon as you try g=e+f;
you will get an error. The compiler doesn't know for sure how to put an A into a B. This prudence is justified by common wisdom: All apes are annimals, but all animals are not necessarily apes.
如果Derived
的字段多于Base
,这甚至更加明显:应如何更灵活地初始化它们?基本上,如何告诉编译器他应该如何用其他方法制作Derived
?有了构造函数!
And this is even more obvious if Derived
has more fields than Base
: how should teh compilier initialise them ? Basically, how to tell the compiler how he shall make a Derived
out of something else ? With a constructor !
struct Derived : public Base {
Derived()=default;
Derived(const Base& a) : Base(a) { cout<<"construct B from A\n"; }
};
定义好后,一切都会按预期进行:
Once you have defined this, everything works as you'd expect:
g=e+f; // will automatically construct a Derived from the result
// and then execute `Derived`'s default `operator=` which
// will call `Base`'s `operator=`
这里有一个实时演示.
这篇关于基类中的运算符+重载,并在派生类中使用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!