我有一个Figure层次结构作为基类,还有几个子类CircleSquare,ecc。我想重载<中的Figure运算符以按例如对数字进行排序。 Surface在基类中实现。

这是我的代码:

//Figure.hpp
class Figure
{
public:
    virtual float surface() const = 0;
    virtual float perimeter() const = 0;

    friend bool operator<(const Figure& lhs, const Figure& rhs);
    friend bool operator>=(const Figure& lhs, const Figure& rhs);
}

//Figure.cpp
bool operator<(const Figure& lhs, const Figure& rhs)
{
    return lhs.surface() < rhs.surface();
}

bool operator>=(const Figure& lhs, const Figure& rhs)
{
    return lhs.surface() >= rhs.surface();
}

//Square.hpp
class Square : public Figure{
public:
    Square(float size);
    float surface() const{
        return mSize * mSize;
    };
    float perimeter()const{
        return mSize * 4;
    }
private:
    float mSize;
};


问题是在运行时出现错误:

libc++abi.dylib: Pure virtual function called!


lhs.surface()

我在<中用LinkedList调用Template运算符:

template <typename T>
void List<T>::insertNewNode(T& dataIn)
{
    if(isEmpty())
    {
        insertBegin(dataIn);
    }else //otherwise
    {
        if(dataIn < *startPtr->data)
        {
            insertBegin(dataIn);
        }
        else if(dataIn >= *endPtr->data) /
        {
            insertEnd(dataIn);
        }
        else
        {
            //...
        }
    }
}

//main.cpp
List<Figure> *list = new List<Figure>();
Figure *square = new Square(46);
list->insertNewNode(*square);


编辑
https://github.com/sanandrea/GenericLinkedList

这可行吗,或者我做错了什么?

最佳答案

问题既是Object Slicing也是未定义的行为。

您通过插入值

void List<T>::insertNewNode(T& dataIn)


没关系由于您通过引用传递了它,因此多态性将得以保留。但是,当您以后调用insertBegininsertEnd实际创建节点时,将其传递给T

void List<T>::insertBegin(T dataIn)


由于对象切片,此处dataIn失去了多态性。在新创建的节点中存储指向参数的指针时,您还具有未定义的行为:

ListNode<T> * newPtr = new ListNode<T>(&dataIn); //creates new node


请注意,&dataIn是指向insertBegin参数的指针,而不是指向在dataIn中传递的insertNewNode(T& dataIn)的指针。

您的节点中也有“对象切片”:T ListNode<T>::getData() //returns data stored in node

10-08 20:02