Наряду с вышеупомянутыми проблемами, главная проблема, с которой я столкнулся, была на самом деле построена на разных платформах, что может быть не тем, о чем вы просите, но может быть чем-то, на что следует обратить внимание.
OS X особенно виновата в этом при использовании Apple Distribution of Java (почему кто-то захочет выпустить свою собственную упаковку Java, я не знаю, но это отдельный аргумент, а в OSX я не думаю, что у вас есть выбор, кроме как использовать их Java). Библиотеки, на которые вы можете положиться, а можете и не положиться, находятся в совершенно разных каталогах, например, библиотеки вместо lib, если моя память мне правильно служит. И IBM Java, я думаю, упаковывает классы в разные банки в некоторых случаях. Смешно !!
Надеюсь, это поможет.
Для такого рода иерархии я определенно следую совету Скотта Мейера по эффективному 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;
}
На днях у меня была такая же проблема, и я придумал следующее решение:
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;
}
};
То, что мне в этом не нравится, это проверка типажа. Что ты об этом думаешь?