派生对象没有使用自己的操作符=

Derived objects are not using their own operator =

本文关键字:自己的 操作符 对象 派生      更新时间:2023-10-16

我有以下的类层次结构:

#include <iostream>
using namespace std;
class Figure
{
    public:
    Figure() {};
    virtual void print() const { cout << "Figure" << endl; };
    Figure& operator=(const Figure& rhs)
    {
        if (this != &rhs)
        {
            cout << "Called figure equals" << endl;
        }
        return *this;
    };
};
class Circle : public Figure
{
public:
    Circle() {};
    virtual void print() const { cout << "Circle" << endl; };
    Circle& operator=(const Circle& rhs)
    {
        if (this != &rhs)
        {
            Figure::operator=(rhs);
            cout << "Called circle equals" << endl;
        }
        return *this;
    };
};

当我向FigureContainer添加派生对象时,对象没有使用自己的操作符=,但它们使用基类操作符并作为基类实例进入数组,因此我不能从派生类调用"打印"函数。

class FigureContainer
{
public:
    FigureContainer() { };
    int size = 0;
    Figure figures[20];
    void add(const Figure& figure)
    {
        figure.print(); // Called circle print !
        figures[size] = figure; // Used base = operator instead of the derived figure class
        size++;
    };
};
int main()
{
    FigureContainer* figures = new FigureContainer();
    (*figures).add(*new Circle());
    (*figures).figures[0].print(); // called abstract print !
    system("pause");
    return 0;
}

.

Output :
Circle
Called figure equals
Figure

我做错了什么?

在c++中,=不是虚的。编译器决定哪个类将在编译时提供操作符。赋值figures[i] = ...由左侧对象的类型处理,因此调用Figure的操作符。

这是OK的,因为非指针赋值不应该是多态的:Figure对象的数组只能存储没有对象切片的Figure对象。存储Circle将删除对象的所有特定于圆的属性,只留下Figure部分。

可以通过将figures设置为一个智能指针数组来解决这个问题。这将保留存储在容器中的对象的子类型,并使使用哪个赋值操作符的问题变得无关紧要。