[英]C++ implementation of template class with pure virtual functions in it
我正在使用一个必须能够处理不同类型的数据(最终甚至不是数学数据)的计算器,但是我仍然坚持执行Complex
类。 这是我要实现的目标:
vectorSpace
,我将从中抽象出其他具体类,例如Complex
, Vector等等。 我为什么要这样创建它? 好吧, 所有向量空间的唯一共同特征是它们允许两个运算:相同空间类型的求和运算,以及同一字段中的点积 (或标量积 ?不确定英文的实际名称)。 该字段的类型可能非常不同( 整数 , 双精度型 , 字符串等),因此我想使用模板进行设置 。 然后,每个派生类将为模板指定字段的数据类型并实现虚拟操作
Complex
,它将从vectorSpace
派生,将double指定为数据类型,定义sum和dot product的运算,然后将所有其余可用运算相加。 这是我现在针对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
类以使其被识别为具体而非抽象。 我在哪里做错了?
问题 :
您需要在您的具体派生类Complex
重写抽象模板类vectorSpace
的以下纯虚拟成员方法:
virtual vectorSpace<T>& sum(const vectorSpace<T>&) const = 0;
virtual vectorSpace<T>& dotProduct(const T&) const = 0;
当前,您提供了两个重载的成员方法,但是由于使用了不同的返回类型(例如Complex&
!= vectorSpace<double>&
),它们没有被覆盖(在将override
关键字添加到这两个成员方法之后尝试编译):
Complex& Complex::sum(const Complex &z) const {
return *this + z;
}
Complex& Complex::dotProduct(const double& d) const {
return *this * d;
}
可能的解决方案 :
将Complex
作为附加模板参数传递给基类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_cast
,否则您无法使用该实例的const
成员方法将非const
引用传递给该实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.