包含纯虚函数的模板类的C ++实现

时间:2018-08-11 13:33:29

标签: c++ templates pure-virtual

我正在使用一个必须能够处理不同类型的数据(最终甚至不是数学数据)的计算器,但我仍坚持使用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类来使它识别为具体的而不是抽象的。我在哪里做错了?

1 个答案:

答案 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)。