C++ C++;==使用共享\u ptr的抽象基类子类的运算符

C++ C++;==使用共享\u ptr的抽象基类子类的运算符,c++,dynamic,shared-ptr,C++,Dynamic,Shared Ptr,我得到了一个抽象基类“Parent”,它有一个纯虚方法和一个子类“child”,实现了这个方法和一个成员“value”。我将子类的对象实例化为shared_ptr,作为动态绑定的一种方式。我在这里使用共享的ptr而不是引用,因为我将这些对象存储在std::vector中 现在我想比较源代码底部定义的两个对象“someObject”和“anotherObject”。因此,我覆盖了相应子类中的==运算符。但是,只调用共享的\u ptr的==运算符。我可以对后面的动态绑定对象进行比较吗 /* * Pa

我得到了一个抽象基类“Parent”,它有一个纯虚方法和一个子类“child”,实现了这个方法和一个成员“value”。我将子类的对象实例化为shared_ptr,作为动态绑定的一种方式。我在这里使用共享的ptr而不是引用,因为我将这些对象存储在std::vector中

现在我想比较源代码底部定义的两个对象“someObject”和“anotherObject”。因此,我覆盖了相应子类中的==运算符。但是,只调用共享的\u ptr的==运算符。我可以对后面的动态绑定对象进行比较吗

/*
* Parent.h
*/
class Parent{
public:
    virtual ~Parent(){};
    virtual void someFunction() = 0;
};


/*
* Child.h
*/
class Child : public Base{
private:
    short value;

public:
    Child(short value);
    virtual ~Child();
    bool operator==(const Child &other) const;
    void someFunction();
};


/*
* Child.cpp
*/
#include "Child.h"

Child::Child(short value):value(value){}
Child::~Child() {}
void Child::someFunction(){...}

bool Child::operator==(const Child &other) const {
  if(this->value==other.value){
      return true;
  }
  return false;
}


/*
* Some Method
*/
std::shared_ptr<Parent> someObject(new Child(3));
std::shared_ptr<Parent> anotherObject(new Child(4));
//!!!calls == operator for shared_ptr, but not for Child
if(someObject==anotherObject){
//do sth
}
/*
*家长
*/
班级家长{
公众:
虚拟~Parent(){};
虚函数()=0;
};
/*
*Child.h
*/
类子:公共基{
私人:
短期价值;
公众:
儿童(短值);
虚拟~Child();
布尔运算符==(常量子项和其他)常量;
void someFunction();
};
/*
*Child.cpp
*/
#包括“Child.h”
Child::Child(短值):value(值){}
子项::~Child(){}
void Child::someFunction(){…}
布尔子对象::运算符==(常量子对象和其他)常量{
如果(此->值==其他.value){
返回true;
}
返回false;
}
/*
*某种方法
*/
std::shared_ptr someObject(新的子对象(3));
std::共享另一个对象(新的子对象(4));
//!!!calls==用于共享_ptr的运算符,但不用于子级
if(someObject==另一个对象){
//做某事
}
我很感激这里的任何意见!多谢各位


最好的方法是,当静态已知类型为
父级
(而且是)时,您需要为
父级
定义一个
运算符==

有一个虚拟的
操作符==
是有问题的,但是假设你在类
父类
中有一些
操作符==
,无论是否虚拟,那么就这样做

std::shared_ptr<Parent> someObject(new Child(3));
std::shared_ptr<Parent> anotherObject(new Child(4));

//calls == operator for Parent
if( *someObject == *anotherObject){
//do sth
}
std::shared_ptr someObject(新的子对象(3));
std::共享另一个对象(新的子对象(4));
//calls==父级的运算符
如果(*someObject==*另一个对象){
//做某事
}

如果没有解引用
*
s(或某些等效项),您将只是比较
共享的\u ptr
实例,正如您所发现的那样。

当静态已知类型是
父级
(确实是)时,您需要为
父级
定义一个
操作符==

有一个虚拟的
操作符==
是有问题的,但是假设你在类
父类
中有一些
操作符==
,无论是否虚拟,那么就这样做

std::shared_ptr<Parent> someObject(new Child(3));
std::shared_ptr<Parent> anotherObject(new Child(4));

//calls == operator for Parent
if( *someObject == *anotherObject){
//do sth
}
std::shared_ptr someObject(新的子对象(3));
std::共享另一个对象(新的子对象(4));
//calls==父级的运算符
如果(*someObject==*另一个对象){
//做某事
}
如果没有解引用
*
s(或一些等效项),您将只是比较
共享的\u ptr
实例,正如您所发现的那样。

因为您需要更改
if
语句来比较对象本身而不是指针

此外,如果存在需要特殊处理以确定其是否相等的子类型,则您的
运算符==
需要遵从虚拟函数来进行实际比较

bool Parent::operator==(const Parent& other) const
{
    return equals(other);
}

bool Child::equals(const Parent& other) const
{
    Child * otherChild = dynamic_cast<Child*>(&other);
    if (otherChild != NULL)
        // compare child to child
    else
        // compare child to other type
}
bool Parent::operator==(常量父项和其他)常量
{
回报等于(其他);
}
布尔子对象::等于(常量父对象和其他)常量
{
Child*otherChild=dynamic_cast(&other);
if(otherChild!=NULL)
//儿童比较
其他的
//将child与其他类型进行比较
}
因为您需要更改
if
语句来比较对象本身而不是指针

此外,如果存在需要特殊处理以确定其是否相等的子类型,则您的
运算符==
需要遵从虚拟函数来进行实际比较

bool Parent::operator==(const Parent& other) const
{
    return equals(other);
}

bool Child::equals(const Parent& other) const
{
    Child * otherChild = dynamic_cast<Child*>(&other);
    if (otherChild != NULL)
        // compare child to child
    else
        // compare child to other type
}
bool Parent::operator==(常量父项和其他)常量
{
回报等于(其他);
}
布尔子对象::等于(常量父对象和其他)常量
{
Child*otherChild=dynamic_cast(&other);
if(otherChild!=NULL)
//儿童比较
其他的
//将child与其他类型进行比较
}

一般来说,不要比较多态类,它不好看。实际上,一次不要对多个多态对象做任何事情。一般来说,不要比较多态类,这不太好。实际上,一次不要处理多个多态对象。我想,与其将子对象与另一种类型进行比较,还不如简单地返回false。(也许为了清楚起见保留评论)@MooingDuck,大多数时候你是对的,但这取决于你如何定义“平等”。例如,您可以使用一个键字段来确定等价性。@Markransem:非常感谢,这对我很有用。因为other是一个常量,所以我还必须创建动态_cast常量,如下所示:。还有一个问题:为什么我可以完全遵从虚拟函数?只是为了避免抽象类成为纯粹的虚拟类?@Chris,通常只有子类才知道如何正确地比较自己。如果父级可以完全实现equals运算符而不需要子级的任何帮助,那么根本就不需要使用虚拟调用。我可以想象,在这种情况下,不必将子级与另一种类型进行比较,只需返回false即可。(也许为了清楚起见保留评论)@MooingDuck,大多数时候你是对的,但这取决于你如何定义“平等”。例如,您可以使用一个键字段来确定等价性。@Markransem:非常感谢,这对我很有用。因为other是一个常量,所以我还必须创建动态_cast常量,如下所示:。还有一个问题:为什么我可以完全遵从虚拟函数?只是为了避免抽象类成为纯粹的虚拟类?@Chris,通常只有子类才知道如何正确地比较自己。如果父级可以完全实现equals运算符而不需要子级的任何帮助,则根本不需要使用虚拟调用