我正在使用一个必须能够处理不同类型的数据(最终甚至不是数学数据)的计算器,但我仍坚持使用Complex
数字类的实现。这是我要实现的目标:
vectorSpace
的抽象模板类,我将从中抽象出其他具体类,例如Complex
数字, Vector s等。为什么要这样创建它?好吧, ALL 向量空间的唯一共同特征是它们允许两个操作:具有相同空间类型的 sum 操作和点积(或标量产品?不确定英文的真实名称)。该字段的类型可能非常不同(整数,双,字符串等),所以我想使用一个模板。然后,每个派生类将为模板指定字段的数据类型并实现虚拟操作
Complex
派生的派生类vectorSpace
,将double指定为数据类型,定义 sum 和点积的操作,然后添加所有剩余的可用操作。这是我目前vectorSpace
类的代码(完全写为.h文件):
#ifndef VECTORSPACE_H
#define VECTORSPACE_H
template <class T>
class vectorSpace
{
public:
virtual vectorSpace<T>& sum(const vectorSpace<T>&) const =0;
virtual vectorSpace<T>& dotProduct(const T&) const =0;
};
#endif // VECTORSPACE_H
在complex.h中,我有这个:
#ifndef COMPLEX_H
#define COMPLEX_H
#include "vectorspace.h"
class Complex : public vectorSpace<double> {
private:
double re, im;
public:
Complex(double r=0, double i=0);
double real() const;
double imag() const;
Complex& operator +(const Complex& z) const;
Complex& sum(const Complex& z) const;
Complex& operator *(double d) const;
Complex dotProduct(double d) const;
//other functions for Complex
};
#endif // COMPLEX_H
最后是我完成的实现:
#include "complex.h"
Complex::Complex(double r, double i) : re(r), im(i) {}
double Complex::real() const{
return re;
}
double Complex::imag() const{
return im;
}
Complex& Complex::operator +(const Complex& z) const{
Complex *aux = new Complex(); //new is not allowed for an abstract class but it should not be abstract anymore
aux->re = re + z->re;
aux->im = im + z->im;
return *aux;
}
Complex& Complex::sum(const Complex &z) const{
return *this + z;
}
/* I've tried even with this, but it does not work!!
vectorSpace<double>& Complex:sum(const vectorSpace<double>& z) const{
return *this + z;
}
*/
Complex Complex::operator *(double d) const{
Complex aux;
aux.re = re * d;
aux.im = im * d;
return aux;
}
Complex& Complex::dotProduct(const double& d) const{
return *this * d;
}
这只是我所做的最后一次实现尝试。我尝试了各种组合,但是仍然无法获得Complex
类来使它识别为具体的而不是抽象的。我在哪里做错了?
答案 0 :(得分:0)
问题:
您需要在具体的派生类vectorSpace
中覆盖抽象模板类Complex
的以下纯虚拟成员方法:
virtual vectorSpace<T>& sum(const vectorSpace<T>&) const = 0;
virtual vectorSpace<T>& dotProduct(const T&) const = 0;
当前,您提供了两个重载的成员方法,但是由于使用了不同的返回类型(即{{1}),所以它们没有任何替代(在将override
关键字添加到这两个成员方法之后尝试编译) }!= Complex&
)
vectorSpace<double>&
可能的解决方案:
将Complex& Complex::sum(const Complex &z) const {
return *this + z;
}
Complex& Complex::dotProduct(const double& d) const {
return *this * d;
}
作为附加模板参数传递给基类Complex
。使用此附加模板参数的类型来更改纯虚拟成员方法的签名。
可能的实施方式 [Try It Online]:
vectorSpace
我做了一些更改,因为您的堆分配纯粹是开销和危险,并且您不能使用该实例的template< typename T, typename ValueT >
class VectorSpace {
public:
virtual const ValueT sum(const ValueT&) const noexcept = 0;
virtual const ValueT dotProduct(T) const noexcept = 0;
};
class Complex : public VectorSpace< double, Complex > {
private:
double re, im;
public:
Complex(double r, double i) noexcept
: re(r), im(i) {}
// Do not worry about the const return values;
// C++17's Guaranteed Copy Elision will take care of that.
const Complex operator+(const Complex& z) const noexcept {
return Complex(re + z.re, im + z.im);
}
const Complex operator*(double d) const noexcept {
return Complex(re * d, im * d);
}
const Complex sum(const Complex& z) const noexcept override {
return *this + z;
}
const Complex dotProduct(double d) const noexcept override {
// Note that this is not a general dot or inner product.
// This is just scalar multiplication.
return *this * d;
}
};
int main() {
Complex c(1.0, 2.0); // As concrete as can be ;-)
return 0;
}
成员方法将非const
引用传递给该实例,除非您确实想滥用const
)。