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