Что правильный путь состоит в том, чтобы перегрузить оператор == для иерархии классов?

Наряду с вышеупомянутыми проблемами, главная проблема, с которой я столкнулся, была на самом деле построена на разных платформах, что может быть не тем, о чем вы просите, но может быть чем-то, на что следует обратить внимание.

OS X особенно виновата в этом при использовании Apple Distribution of Java (почему кто-то захочет выпустить свою собственную упаковку Java, я не знаю, но это отдельный аргумент, а в OSX я не думаю, что у вас есть выбор, кроме как использовать их Java). Библиотеки, на которые вы можете положиться, а можете и не положиться, находятся в совершенно разных каталогах, например, библиотеки вместо lib, если моя память мне правильно служит. И IBM Java, я думаю, упаковывает классы в разные банки в некоторых случаях. Смешно !!

Надеюсь, это поможет.

47
задан Michael Kristofik 9 November 2009 в 14:47
поделиться

2 ответа

Для такого рода иерархии я определенно следую совету Скотта Мейера по эффективному C ++ и избегаю каких-либо конкретных базовых классов. Вы, кажется, делаете это в любом случае.

Я бы реализовал operator == как бесплатные функции, возможно, друзья, только для конкретных типов классов листовых узлов.

Если базовый класс должен иметь элементы данных, тогда я бы предоставил (вероятно, защищенную) невиртуальную вспомогательную функцию в базовом классе (например, isEqual ), которую производные классы ' operator == могли бы используйте.

Например,

bool operator==(const B& lhs, const B& rhs)
{
    lhs.isEqual( rhs ) && lhs.bar == rhs.bar;
}

Избегая использования оператора == , который работает с абстрактными базовыми классами, и сохраняя функции сравнения защищенными, вы не в клиентском коде никогда не возникало случайных откатов, когда сравнивается только базовая часть двух объектов с разными типами.

Я не уверен, реализовал бы я функцию виртуального сравнения с dynamic_cast , я бы неохотно делать это, но если бы в этом была доказанная необходимость, я бы, вероятно, выбрал чистую виртуальную функцию в базовом классе ( не operator == ), которая затем была переопределена в конкретном производном classes как-то вроде этого, используя оператор == для производного класса.

bool B::pubIsEqual( const A& rhs ) const
{
    const B* b = dynamic_cast< const B* >( &rhs );
    return b != NULL && *this == *b;
}
20
ответ дан 26 November 2019 в 19:53
поделиться

На днях у меня была такая же проблема, и я придумал следующее решение:

struct A
{
    int foo;
    A(int prop) : foo(prop) {}
    virtual ~A() {}
    virtual bool operator==(const A& other) const
    {
        if (typeid(*this) != typeid(other))
            return false;

        return foo == other.foo;
    }
};

struct B : A
{
    int bar;
    B(int prop) : A(1), bar(prop) {}
    bool operator==(const A& other) const
    {
        if (!A::operator==(other))
            return false;

        return bar == static_cast<const B&>(other).bar;
    }
};

struct C : A
{
    int baz;
    C(int prop) : A(1), baz(prop) {}
    bool operator==(const A& other) const
    {
        if (!A::operator==(other))
            return false;

        return baz == static_cast<const C&>(other).baz;
    }
};

То, что мне в этом не нравится, это проверка типажа. Что ты об этом думаешь?

12
ответ дан 26 November 2019 в 19:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: