我在库中有两个类:
class A
{
public:
int x;
};
template <class T>
class B : public A
{
public:
T y;
};
并有方法:
... Method(A &a, A &b);
如果a、b总是具有相同类型的,如何比较a和b的y
B <T>
,但T的类型未知?
当您有一个函数时,
Method(A a, A b);
由于对象切片,您丢失了对象的B
部分。
如果要保留对象的B
部分,则必须使用引用或指针。
Method(A const& a, A const& b);
或
Method(A const* a, A const* b);
为了使Method
正确工作,您必须提供一种将对象视为B
的方法。您可以使用A
中的virtual
函数来使用它。
class A
{
public:
int x;
virtual int compare(A const& rhs) const
{
return (this->x - rhs.x);
}
};
并确保覆盖CCD_ 7中的功能。
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);
}
};
然后,在Method
中,
Method(A const& a, A const& b)
{
int r = a.compare(b);
}
一个可能的解决方案是创建一个虚拟函数来进行比较。
在派生类中实现的主体中,类型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;
}
};
您可以将Method
定义为模板方法。
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;
}
使用这种方法,您不必知道Method
中T
的类型。但当您调用它时,必须指定T
:
bool areEqual = Method<int>(a, b);
也许这对你来说没有问题。
请注意,无论何时将B<T>
分配给类型为A
的变量,都会丢失特定于B<T>
的信息(在这种情况下,y
的值会丢失)。这就是为什么我更改了Method
的签名,以便获取引用而不是值。