派生对象不使用自己的operator =

时间:2016-06-26 14:43:30

标签: c++

我有以下类层次结构:

#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时,对象没有使用自己的operator =,但是他们使用基类oprerator并作为基类instaces进入数组,所以我不能调用&#34 ;打印&#34;来自派生类的函数。

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

我做错了什么?

1 个答案:

答案 0 :(得分:2)

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

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

您可以通过使figures成为智能指针数组来解决此问题。这将保留容器中存储的对象的子类型,并且它将使得哪个赋值运算符使用不相关的问题。