我正在用operator==编写全局类比较函数,用于一个大型框架,其中类倾向于继承多个类或具有深度继承(类A继承自B,B继承自C等)。为了便于管理,我想我应该为基类设置一个比较函数,然后从基类继承的类除了检查它们自己的成员之外,还会使用这个函数。
在搜索时,我发现了用于比较类的示例代码,但没有涉及继承的示例。下面我为基类Foo做了一个简单的示例,Bar继承了这个示例:
#include <iostream>
class Foo
{
public:
int m_a;
Foo(int i) : m_a(i) {}
};
inline static bool operator==(const Foo& l, const Foo& r)
{
return l.m_a == r.m_a;
}
static void coutResult(const Foo& l, const Foo&r)
{
std::cout << "l.m_a == " << l.m_a << ", "
<< "r.m_a == " << r.m_a << ", "
<< (l == r ? "true" : "false") << std::endl;
}
class Bar :
public Foo
{
public:
int m_b;
Bar(int i, int j) : Foo(i), m_b(j) {}
};
inline static bool operator==(const Bar& l, const Bar& r)
{
return ((Foo)l) == ((Foo)r) &&
l.m_b == r.m_b;
}
static void coutResult(const Bar& l, const Bar& r)
{
std::cout << "l.m_a == " << l.m_a << ", "
<< "l.m_b == " << l.m_b << ", "
<< "r.m_a == " << r.m_a << ", "
<< "r.m_b == " << r.m_b << ", "
<< (l == r ? "true" : "false") << std::endl;
}
int main(int argc, char** argv) {
Foo a(1);
Foo b(1);
Foo c(2);
coutResult(a, b);
coutResult(a, c);
coutResult(a, c);
Bar d(1, 2);
Bar e(1, 2);
Bar f(1, 3);
Bar g(2, 2);
coutResult(d, e);
coutResult(d, f);
coutResult(d, g);
coutResult(e, f);
coutResult(f, g);
coutResult(f, g);
return 0;
}它似乎工作得很好,但我想知道是否有一个“标准”的方式去做这个或一个更好的解决方案。我看到这个解决方案有两个问题:
发布于 2015-06-17 04:53:55
您的设计有可能产生意想不到的结果。
如果您的main是:
int main(int argc, char** argv)
{
Foo a(1);
Bar d(1, 2);
coutResult(a, d);
return 0;
}最后将Foo对象与Bar对象进行比较,输出如下:
l.m_a == 1, r.m_a == 1, true如果你对这个结果感到满意,你可以坚持你现在的设计。不过,我认为这是一个不适当的结果。
我的建议:
Foo成为一个纯虚拟类,以避免出现这种情况。operator=()成为一个纯虚拟成员函数-- Foo。在派生类实现可以利用的Foo中提供一个实现。dynamic_cast确保您正在将Bar与另一个Bar进行比较,而不是将Bar与另一个子类型的Foo进行比较。这是一个演示这些想法的程序。
#include <iostream>
class Foo
{
public:
int m_a;
Foo(int i) : m_a(i) {}
virtual bool operator==(const Foo& r) const = 0;
};
bool Foo::operator==(const Foo& r) const
{
return (this->m_a == r.m_a);
}
static void coutResult(const Foo& l, const Foo&r)
{
std::cout << std::boolalpha << (l == r) << std::endl;
}
class Bar : public Foo
{
public:
int m_b;
Bar(int i, int j) : Foo(i), m_b(j) {}
virtual bool operator==(const Foo& r) const
{
Bar const* barPtr = dynamic_cast<Bar const*>(&r);
if ( barPtr == nullptr )
{
return false;
}
if ( !Foo::operator==(r) )
{
return false;
}
return (this->m_b == barPtr->m_b);
}
};
class Baz : public Foo
{
public:
double m_c;
Baz(int i, double c) : Foo(i), m_c(c) {}
virtual bool operator==(const Foo& r) const
{
Baz const* bazPtr = dynamic_cast<Baz const*>(&r);
if ( bazPtr == nullptr )
{
return false;
}
if ( !Foo::operator==(r) )
{
return false;
}
return (this->m_c == bazPtr->m_c);
}
};
int main(int argc, char** argv)
{
Bar bar1(1, 2);
Bar bar2(1, 2);
Bar bar3(2, 2);
Baz baz1(1, 10.8);
Baz baz2(1, 10.8);
coutResult(bar1, bar2);
coutResult(bar1, bar3);
coutResult(bar1, baz1);
coutResult(baz1, baz2);
return 0;
}输出:
true
false
false
truehttps://stackoverflow.com/questions/30882301
复制相似问题