簡體   English   中英

全局類與繼承的比較

[英]Global class comparison with inheritance

我寫的全球分類比較功能與operator==一個大框架,類往往繼承幾類或有很深的繼承(類A繼承自BB從繼承C等)。 為了使事情易於管理,我認為我將為基類提供一個比較函數,然后從基類繼承的類除了檢查自己的成員外,還將使用該函數

在谷歌搜索中,我發現了用於比較類的示例代碼,但沒有涉及繼承的示例。 下面,我為Bar繼承了一個基本類Foo的簡單示例:

#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;
}

似乎工作正常,但我想知道是否有“標准”方法可以解決此問題或提供更好的解決方案。 我看到此解決方案有兩個問題:

  • 每次開發人員將成員添加到某個類中時,他們都必須知道更新相應的比較功能,但我看不出如何避免這種情況

  • 任何成員都不能設為私有,並且考慮到該框架很大,這是一個問題。 我知道的唯一解決方案是讓每個私人成員都吸氣

您的設計有可能產生意想不到的結果。

如果您的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

如果您對該結果感到滿意,則可以保留當前的設計。 但是,我認為這是不合適的結果。

我的建議:

  1. 使Foo成為純虛擬類以避免這種情況。
  2. 使operator=()成為純虛擬成員函數Foo Foo提供一個實現,派生類實現可以利用。
  3. 實現該函數的派生類。 使用dynamic_cast確保將Bar與另一個Bar進行比較,而不是將BarFoo另一個子類型進行比較。

這是一個演示這些想法的程序。

#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
true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM