本文介绍了基类中的运算符+重载,并在派生类中使用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有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" derivedCould 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=`

这里有一个实时演示.

这篇关于基类中的运算符+重载,并在派生类中使用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:16