TransWikia.com

How to compare using base class in derived class data

Stack Overflow Asked by Sao Haruka on December 22, 2021

I have base class and derived class in C++.
I want to determine if the data of the derived class is the same using the pointers of the base class.

enum type

enum class FruitType: int{
    Apple,
    Orange,
};

base class

class Base{
public:
    Base(FruitType t): fruit_type(t){}
    FruitType fruit_type;
};

derived class

class Apple : public Base{
public:
    Apple(int i): Base(FruitType::Apple), foo(i){}
    int foo;
};
class Orange : public Base{
public:
    Orange(float f): Base(FruitType::Orange), bar(f){}
    float bar;
}; 

initialize

// initialize
std::vector<Base*> fruit_list_ = { 
                new Apple(42),
                new Orange(0.f),
                new Apple(1) };

Is there any way to check with HasSameData()?

Base* HasSameData(const Base* pCompare){
    for (const auto& list : fruit_list_) 
    {
        if( pCompare->fruit_type == list->fruit_type ){
            // how to check same data...?
            if( /* ... */ ){
                return list;
            }
        }
    }
    return nullptr;
}

int main(){
    // check same data
    Base* pCompare = fruit_list_[2];
    if(HasSameData(pCompare)){
        // I want to return fruit_list_[2] pointer...
    }
}

2 Answers

You could add an abstract method sameData() to the base case

class Base{
public:
    Base(FruitType t): fruit_type(t){}
    FruitType fruit_type;
    virtual bool sameData(const Base& other) const = 0;
};

Override in the derived classes:

class Apple : public Base{
public:
    Apple(int i): Base(FruitType::Apple), foo(i){}
    int foo;
    virtual bool sameData(const Base& other) const {
        const Apple* apple = dynamic_cast<const Apple*>(&other);
        return apple && apple->foo == foo;
    }
};

class Orange : public Base{
public:
    Orange(float f): Base(FruitType::Orange), bar(f){}
    float bar;
    virtual bool sameData(const Base& other) const {
        const Orange* orange = dynamic_cast<const Orange*>(&other);
        return orange && orange->bar == bar;
    }
};

And use it as follows:

// how to check same data...?                                       
if( pCompare->sameData(*list) ){

Answered by wcochran on December 22, 2021

The simplest way is to use a virtual function to compare equality and implement the comparison logic in the body of the virtual function.

class Base{
public:
    Base(FruitType t): fruit_type(t){}
    FruitType fruit_type;

    virtual bool Equals(Base *other) const = 0;
};

class Apple : public Base{
public:
    Apple(int i): Base(FruitType::Apple), foo(i){}
    int foo;

    bool Equals(Base *other) const override {
        if (other->fruit_type != FruitType::Apple)
            return false;
        return foo == ((Apple*)other)->foo;
    }
};

class Orange : public Base{
public:
    Orange(float f): Base(FruitType::Orange), bar(f){}
    float bar;

    bool Equals(Base *other) const override {
        if (other->fruit_type != FruitType::Orange)
            return false;
        return bar == ((Orange*)other)->bar;
    }
}; 

Then write your comparison function like this:

bool HasSameData(const Base* pCompare){
    for (const Base *fruit : fruit_list_) 
        if (pCompare->Equals(fruit))
            return true;
    return false;
}

Answered by Zachary Turner on December 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP