C++:多态性和运算符重载

C++ : Polymorphism and operator overloading

本文关键字:运算符 重载 多态性 C++      更新时间:2023-10-16

当我使用抽象基类时,我很难弄清楚重载比较运算符必须如何完成。主要问题是使用该基类实现多态性,因为它是抽象的,所以无法实例化,所以我不得不使用指向该基类的指针来访问派生类方法。我会放一些代码来更好地描述这种情况:

template <typename _Tp>
class Base 
{
    private: 
       _Tp attr ; 
    public: 
       foo() = 0 ; 
       friend bool operator == ( Base* b1, Base* b2)  
       {
           return ( b1.attr == b2.attr ) ;
       }
}; 
template <typename _Tp> class Derived_1 : public Base<_Tp> { /.../ } ;
template <typename _Tp> class Derived_2 : public Base<_Tp> { /.../ } ; 
int main (void)
{
    vector<Base*<int> > * v = new vector<Base*<int> > (2,0) ; 
    v[0] = new Derived_1 () ; 
    v[1] = new Derived_2 () ; 
    if ( (*v)[0] == (*v)[1] ) { /.../ }
    return 0 ;
}

因此,在这一点上,您会注意到(*v)[0] == (*v)[1]Base*的指针比较。我想知道是否有一种方法可以重载这两个指针之间的比较运算符,因为基类中定义的重载运算符从未使用过。

回复后编辑:

由于在我的真实代码中,比较必须是(*v)[0] == (*v)[1],所以我不能比较对象,因为我的数据结构将失去通用性。因此,我想问你的是:

可以对Base指针进行比较吗?怎样

我从编译器那里得到错误,告诉我:

bool运算符==(Base*,Base*)必须具有类或枚举类型的参数。

基类operator==从未被调用的原因是因为行

v[0] == v[1]

比较两个指针——索引0和索引1处的矢量内容。

您可以将其更改为*v[0] == *v[1],它将使用基类运算符进行比较。

然而,在多态设置中使用重载运算符充满了困难。有关这方面的更多信息,请参阅Scott Meyers在"有效C++"中的发言。

使用Boost指针容器库

#include <boost/ptr_container/ptr_vector.hpp>
...
int main()
{
    boost::ptr_vector<Base> v;
    v.push_back(new Derived_1);
    v.push_back(new Derived_2);
    if (v[0] == v[1]) { std::cout << "successn"; }
}

如果要将多态对象存储在使用比较的容器中,Boost Pointer container Library还有ptr_setptr_mapptr_multisetptr_multimap。然而,你提到了一堆。没有boost::ptr_priority_queue。在这种情况下,您只需为std::priority_queue提供自己的比较器即可。

struct BasePtrComp
{
    bool operator()(Base const* lhs, Base const* rhs) const
    {
        return *lhs < *rhs;
    }
};
...
std::priority_queue<Base*, std::vector<Base*>, BasePtrComp> v;

尽管我建议您在这里使用智能指针。

因此,您想要的是在指针比较中比较对象属性,在这种情况下,您需要重载指针的运算符==或ineger。这不是它的工作方式,因为在比较int时需要有某种"instanceOf",但这些并不总是指针。