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);