Я использую шаблон CRTP
для реализации оператора равенства в иерархии классов.Этот код работает, но мне нужно всегда проверять равенство членов BaseClass
в операторе равенства производного класса, например,
c_member == other.c_member && common_elem == other.common_elem;
Если у меня несколько уровней иерархии, этот проект добавляетмного шаблонного кода.Есть ли способ изменить этот код, чтобы производные классы сначала проверяли равенство базовой части (common_elem
переменная-член в этом примере) и, если не верно, выполняли тест на их специальных переменных-членах.
#include "gtest/gtest.h"
#include "gmock/gmock.h"
using namespace ::testing;
#include <iostream>
#include <memory>
using namespace std;
class BaseClass
{
protected:
int common_elem;
public:
explicit BaseClass(int common_elem) : common_elem(common_elem) {}
bool operator==(const BaseClass& other) const
{
return equals(other);
}
bool operator!=(const BaseClass& other) const
{
return (!equals(other));
}
protected:
virtual bool equals(const BaseClass& other) const{
return common_elem == other.common_elem;
}
};
template<class T>
class BaseClassCRTP : public BaseClass
{
protected:
public:
explicit BaseClassCRTP(int common_elem) : BaseClass(common_elem) {}
protected:
virtual bool equals(const BaseClass& other_base) const
{
const T* other = dynamic_cast<const T*>(&other_base);
return other != nullptr && static_cast<const T&>(*this) == *other;
}
private:
bool operator==(const BaseClassCRTP& a) const // force derived classes to implement their own operator==
{
return false;
}
};
class B : public BaseClassCRTP<B>
{
public:
B(int common_elem, int b_member_) : BaseClassCRTP(common_elem), b_member(b_member_) {}
bool operator==(const B& other) const
{
return b_member == other.b_member && common_elem == other.common_elem;
}
private:
int b_member;
};
class C : public BaseClassCRTP<C>
{
public:
C(int common_elem, int c_member_) : BaseClassCRTP(common_elem), c_member(c_member_) {}
bool operator==(const C& other) const
{
return c_member == other.c_member && common_elem == other.common_elem;
}
private:
int c_member;
};
TEST(Experimental, CRTP) {
B b1(1, 1);
B b2(1, 1);
B b3(2, 1);
C c1(1, 1);
C c2(1, 1);
EXPECT_EQ(b1, b2);
EXPECT_NE(b1, b3);
EXPECT_NE(b2, b3);
EXPECT_NE(b1, c1);
EXPECT_NE(c1, b2);
EXPECT_EQ(c1, c2);
}