首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >全局类与继承的比较

全局类与继承的比较
EN

Stack Overflow用户
提问于 2015-06-17 04:23:03
回答 1查看 77关注 0票数 0

我正在用operator==编写全局类比较函数,用于一个大型框架,其中类倾向于继承多个类或具有深度继承(类A继承自BB继承自C等)。为了便于管理,我想我应该为基类设置一个比较函数,然后从基类继承的类除了检查它们自己的成员之外,还会使用这个函数。

在搜索时,我发现了用于比较类的示例代码,但没有涉及继承的示例。下面我为基类Foo做了一个简单的示例,Bar继承了这个示例:

代码语言:javascript
复制
#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;
}

它似乎工作得很好,但我想知道是否有一个“标准”的方式去做这个或一个更好的解决方案。我看到这个解决方案有两个问题:

  • 每次开发人员向某个类添加一个成员时,他们都必须知道以更新相应的比较函数,但我看不出这是如何避免的
  • 任何成员都不能成为私人成员,考虑到框架很大,这是一个问题。我所知道的唯一的解决办法是为每个私人成员做一个吸气器。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-17 04:53:55

您的设计有可能产生意想不到的结果。

如果您的main是:

代码语言:javascript
复制
int main(int argc, char** argv)
{
   Foo a(1);
   Bar d(1, 2);

   coutResult(a, d);

   return 0;
}

最后将Foo对象与Bar对象进行比较,输出如下:

代码语言:javascript
复制
l.m_a == 1, r.m_a == 1, true

如果你对这个结果感到满意,你可以坚持你现在的设计。不过,我认为这是一个不适当的结果。

我的建议:

  1. 使Foo成为一个纯虚拟类,以避免出现这种情况。
  2. 使operator=()成为一个纯虚拟成员函数-- Foo。在派生类实现可以利用的Foo中提供一个实现。
  3. 实现派生类的函数。使用dynamic_cast确保您正在将Bar与另一个Bar进行比较,而不是将Bar与另一个子类型的Foo进行比较。

这是一个演示这些想法的程序。

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
true
false
false
true
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30882301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档