我有一个Figure
层次结构作为基类,还有几个子类Circle
,Square
,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)
没关系由于您通过引用传递了它,因此多态性将得以保留。但是,当您以后调用
insertBegin
或insertEnd
实际创建节点时,将其传递给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
。