C++ 比较派生模板类中的字段

C++ 比较派生模板类中的字段,c++,C++,我在图书馆有两门课: class A { public: int x; }; template <class T> class B : public A { public: T y; }; 如果a、b总是有相同的类型,如何比较a和b中的y B <T> B ,但T的类型未知?当您有一个函数时 Method(A a, A b); 由于对象切片,您丢失了对象的B部分 如果要保留对象的B部分,必须使用引用或指针 Method(A con

我在图书馆有两门课:

class A
{
    public:
    int x;
};

template <class T>
class B : public A
{
    public:
    T y;

};

如果a、b总是有相同的类型,如何比较a和b中的y

B <T>
B

,但T的类型未知?

当您有一个函数时

Method(A a, A b);
由于对象切片,您丢失了对象的
B
部分

如果要保留对象的
B
部分,必须使用引用或指针

Method(A const& a, A const& b);

为了使
方法
正常工作,您必须提供一种方法,将对象视为
B
。您可以使用
a
中的
virtual
功能来使用它

class A
{
    public:
    int x;
    virtual int compare(A const& rhs) const
    {
        return (this->x - rhs.x);
    }
};
并确保覆盖
B
中的功能

template <class T>
class B : public A
{
    public:
    T y;
    virtual int compare(A const& rhs) const
    {
       // Use the base class first.
       int r = A::compare(rhs);

       // If the base class result is adequate, return.
       if ( r != 0 )
       {
          return r;
       }

       // Do a dynamic_cast of the rhs.
       B const* rhsPtr = dynamic_cast<B const*>(&rhs);

       // If the dynamic_cast didn't succeed, need
       // to figure out how to handle the case.
       if ( rhsPtr == nullptr )
       {
          // Add error handling code
       }

       return (this->y - rhsPtr->y);
    }
};

一个可能的解决方案是创建一个虚拟函数来进行比较

在派生类的实现体中,类型
T
是已知的,您将不会遇到任何问题

struct Base {
  ...
  virtual bool same_y(const Base& other) const = 0;
};

template<typename T>
struct Derived : Base {
    T y;
    virtual bool same_y(const Base& other) const {
        return dynamic_cast< const Derived<T>& >(other).y == y;
    }
};
struct Base{
...
虚拟布尔相同(常数基和其他)常数=0;
};
模板
派生结构:基{
T y;
虚拟布尔相同(常数基和其他)常数{
返回动态_cast(other).y==y;
}
};

您可以将
方法
定义为模板方法

template<typename T>
bool Method(const A& a, const A& b)
{
    const B<T>& first = dynamic_cast<const B<T>&>(a);
    const B<T>& second = dynamic_cast<const B<T>&> (b);
    return first.y == second.y;
}
也许这对你来说没问题


请注意,无论何时将
B
分配给
a
类型的变量,都会丢失
B
特定的信息(在这种情况下,
y
的值丢失)。这就是为什么我更改了
方法的签名
,以获取引用而不是值。

“如果a,b始终具有相同的类型b,如何比较a和b的y”-但是
a和
b
具有类型
a
,但是不是
B
你打算如何在你描述的方法中使用a和B访问y?但是如果我不能更改类a和B?@ZregerZ,如果你不能更改类
a
B
,你必须在
方法中包含所有
动态转换
-ing代码。这几乎是不可能的,因为
B
是一个类模板。您不能只将
动态\u转换为
B
,您必须将
动态\u转换为
B
Method
如何知道使用什么
T
。这听起来不像是可维护的代码。@R Sahu,方法只知道a和b有一种类型的字段y。这里,您有切片问题。无论如何,我都会使用
dynamic\u cast
。如果
first
second
是常量引用,您也可以避免复制。如果我不能更改类,该怎么办?
Method(A const& a, A const& b)
{
   int r = a.compare(b);
}
struct Base {
  ...
  virtual bool same_y(const Base& other) const = 0;
};

template<typename T>
struct Derived : Base {
    T y;
    virtual bool same_y(const Base& other) const {
        return dynamic_cast< const Derived<T>& >(other).y == y;
    }
};
template<typename T>
bool Method(const A& a, const A& b)
{
    const B<T>& first = dynamic_cast<const B<T>&>(a);
    const B<T>& second = dynamic_cast<const B<T>&> (b);
    return first.y == second.y;
}
bool areEqual = Method<int>(a, b);