模板函数忽略继承 class 的成员

Template function ignores members from inherited class

我正在尝试编写一个程序来比较一些形状的面积,形状是基础 class。 该程序还有 2 个其他 class 派生自形状 class.

我是这样定义它们的:

class Shape
{
protected:
    string color;
public:
    Shape();
    Shape(string);
    virtual double Perimeter();
    virtual void printMe();
    virtual double Area();
};

class Square:
    public Shape
{
    int x, y;
    double side;
public:
    Square();
    Square(string, int, int, double);
    double Perimeter();
    void printMe();
    double Area();
};

class Circle:
    public Shape
{
    int x, y, radius;
public:
    Circle();
    Circle(string, int, int, int);
    double Perimeter();
    void printMe();
    double Area();
};

在 main 中,我创建了以下对象:

Shape f1, f2("green");
Circle c1, c2("green", 2, 2, 2);
Square p1, p2("blue", 0, 0, 5);

Shape* f3 = &c1;
Shape* f4 = &c2;
Shape* f5 = new Square("blue", 1, 0, 2);
Shape* f6 = &p2;

我想构建一个函数,它接受任何 Shape 对象和 return 具有最大面积的对象。 我这样试过:

template <typename T>
T maxim(initializer_list<T> list) {
    T maxx;
    for (auto i : list)
    {
        if (i.Area() > maxx.Area())
            maxx = i;
    }
    return maxx;
}

在 main 中,我尝试调用函数:

maxim<Shape>({*f3, *f4, *f5, *f6}).printMe();

程序没有任何错误,只显示一个空字符串(因为 maxx 是一个用空字符串初始化的 Shape)。

对象f3f4f5f6在我调用printMe()方法时就显示出来了,所以我想当我调用 maxim 函数,只有成员 color 被分配给对象。没有 xysideradius 成员分配给他们。

我认为问题在于对象只是 Shapes 并且它们只有 color 成员。 有什么方法可以将列表中的对象解释为 Cricles 和 Squares,以便我可以使用 Area() 方法比较它们?

您正在尝试在此处使用多态性。不幸的是,C++ 中的多态性适用于指针或引用,但不适用于普通对象,因为 slicing(感谢 @Jarod42 提供该参考)。

并且由于无法将引用分配给(而是分配给引用对象),因此您不能在容器中使用它们 也不能在初始化列表中使用 .

这意味着您将不得不在 maxim:

中使用好的旧指针
template <typename T>
T* maxim(initializer_list<T*> list) {
    T* maxx = nullptr;
    for (auto i : list)
    {
        if (nullptr == maxx || i->Area() > maxx->Area())
            maxx = i;
    }
    return maxx;
}

从那时起,您将能够做到:

maxim<Shape>({f3, f4, f5, f6})->printMe();