class Number{
public:
virtual int compare(const Number& rhs) =0;
}
class Number2 : public Number{
public:
int compare(const Number& rhs){/* *** */ }
};
class Number3 : public Number{
public:
int compare(const Number& rhs){ /* *** */ }
};
例如。
Number2 f,s;
Number& ref = f;
ref.compare(s);
所以,它调用Number2 :: compare(对s的引用是隐式upcast) 但这是一个问题,因为我应该知道s的类型进行比较。
我可以避免使用RTTI吗?
答案 0 :(得分:2)
有点不清楚你之后会发生什么,但显然你想用不同类型的数字表示C ++类,具有继承关系。
然后让我们考虑整数与理性。有理数只是一个整数除以另一个整数,一个分数,可以指定为一对整数, a / b 。每个整数 x 等于一个有理数,即 x / 1。
所以,每个整数都是一个有理数。有理数值集包括整数值集作为适当的子集。
在C ++中,表达is-a关系的常用方法是类继承。但是这里产生了一个愚蠢的结果:Integer
应该从Rational
继承,因此每个Integer
都是一个Rational
。然而,Rational
实例通常需要保存两个整数来表示其值。使用建议的继承,Integer
实例将保存一个始终为1的整数。更不用说这里根据派生类Rational
定义Integer
的循环关系(当然,可以通过引入Basic_integer
来修复,int
只能是Integer
的typedef,但仍然可以。)
令人高兴的是,有一条出路:不使用类继承,而是使用隐式转换来模拟逻辑is-a关系。
然后我们将Rational
作为不同的第一个定义的类,Integer
作为第二个定义的类,使用构造函数将Rational
转换为Integer
(通过采用Integer
参数的简单方法。为Integer
定义的比较函数适用于Integer
,但是当您将Rational
与Rational
进行比较时,只有Integer
的比较函数匹配,并且通过隐式转换if(condition){
function->setValue(true)
}
else{
function->setValue(false)
}
。
答案 1 :(得分:1)
这可以通过使用双重调度
来完成class Number {
protected:
virtual Number& operator+(const Integer&) = 0;
virtual Number& operator+(const Complex&) = 0;
virtual Number& operator-(const Integer&) = 0;
virtual Number& operator-(const Complex&) = 0;
// For all inherited types
public:
virtual Number& operator+(const Number&) = 0;
virtual Number& operator-(const Number&) = 0;
};
class Integer : public Number {
private:
int I;
protected:
virtual Number& operator+(const Integer&);
virtual Number& operator+(const Complex&);
public:
Integer(int x) : i(x) {}
virtual Number& operator+(const Number&);
// etc.
};
Number& Integer::operator+(const Number& n)
{
return n + *this; // Replace rhs with lhs
}
Number& Integer::operator+(const Integer& n)
{
// Here is some pseudocode
if (i + n.i to big for int int)
{
return LongInteger;
}
else
return Integer(i + n.i);
}
您还可以使用Google double dispatch主题获取更多信息
在你的情况下
不要因为我们从rhs侧执行它而忘记逆向执行中的实现比较
class Number2;
class Number3;
class Number{
public:
virtual int compare(const Number2& rhs) const = 0;
virtual int compare(const Number3& rhs) const = 0;
virtual int compare(const Number& rhs) const = 0;
};
class Number2 : public Number{
protected:
virtual int compare(const Number2& rhs) const { /* your implementation */ }
virtual int compare(const Number3& rhs) const { /* your implementation */ }
public:
int compare(const Number& rhs) const { return rhs.compare(*this); }
};
class Number3 : public Number{
protected:
virtual int compare(const Number2& rhs) const { /* your implementation */ }
virtual int compare(const Number3& rhs) const { /* your implementation */}
public:
int compare(const Number& rhs) const { return rhs.compare(*this); }
};
这是一些示例代码
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
class Number2;
class Number3;
class Number{
public:
virtual int opposite_compare(const Number2& rhs) const = 0;
virtual int opposite_compare(const Number3& rhs) const = 0;
virtual int compare(const Number& rhs) const = 0;
};
class Number2 : public Number{
protected:
virtual int opposite_compare(const Number2& rhs) const;
virtual int opposite_compare(const Number3& rhs) const;
public:
int m_Val;
Number2(int a) : m_Val(a) { }
int compare(const Number& rhs) const { return rhs.opposite_compare(*this); }
};
class Number3 : public Number{
protected:
virtual int opposite_compare(const Number2& rhs) const;
virtual int opposite_compare(const Number3& rhs) const;
public:
int m_Val0;
int m_Val1;
Number3(int a, int b) : m_Val0(a), m_Val1(b) { }
int compare(const Number& rhs) const { return rhs.opposite_compare(*this); }
};
int Number2::opposite_compare(const Number2& rhs) const
{
return m_Val == rhs.m_Val ? 0 : (m_Val > rhs.m_Val ? -1 : 1);
}
int Number2::opposite_compare(const Number3& rhs) const
{
return m_Val == (rhs.m_Val0 + rhs.m_Val1) ? 0 : (m_Val > (rhs.m_Val0 + rhs.m_Val1) ? -1 : 1);
}
int Number3::opposite_compare(const Number2& rhs) const
{
return (m_Val0 + m_Val1) == rhs.m_Val ? 0 : ((m_Val0 + m_Val1) > rhs.m_Val ? -1 : 1);
}
int Number3::opposite_compare(const Number3& rhs) const
{
return (m_Val0 + m_Val1) == (rhs.m_Val0 + rhs.m_Val1) ? 0 : ((m_Val0 + m_Val1) > (rhs.m_Val0 + rhs.m_Val1) ? -1 : 1);
}
int main(){
Number* pOne = new Number2(9);
Number* pTwo = new Number3(6, 3);
std::cout << "One comp Two: " << pOne->compare(*pTwo) << std::endl;
delete pOne;
delete pTwo;
return 0;
}
答案 2 :(得分:1)
这实际上取决于您尝试解决的问题,特别是如果您确实需要多态层次结构。 但是使用代码片段,您提供的模板可能会有所帮助。那是(例如)你声明一个模板化的比较助手:
template<typename TNumber1, typename TNumber2>
class CompareHelper;
然后为不同类型提供模板专业化,例如
template<>
class CompareHelper<int,double>
{
static int compare(const int &i, const double &d)
{
// int to double comparision with an epsilon threshold
return abs(i-d) < 1e-6;
}
}
您可以将此比较助手用作:
int i = 2;
double d = 2 + 1e-8;
int result = CompareHelper<int,double>(i,d);
修改强> 这是int-int的比较,可能有助于理解这个概念:
template<>
class CompareHelper<int,int>
{
static int compare(const int &i1, const int &i2)
{
// int to int
return i1 == i2;
}
}
好处(但可能是有争议的)是它不会为没有提供专业化的类型进行编译。