繁体   English   中英

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

[英]C++ implementation of template class with pure virtual functions in it

我正在使用一个必须能够处理不同类型的数据(最终甚至不是数学数据)的计算器,但是我仍然坚持执行Complex类。 这是我要实现的目标:

  • 抽象模板类称为vectorSpace ,我将从中抽象出其他具体类,例如ComplexVector等等。

我为什么要这样创建它? 好吧, 所有向量空间的唯一共同特征是它们允许两个运算:相同空间类型的求和运算,以及同一字段中的点积 (或标量积 ?不确定英文的实际名称)。 该字段的类型可能非常不同( 整数双精度型字符串等),因此我想使用模板进行设置 然后,每个派生类将为模板指定字段的数据类型并实现虚拟操作

  • 派生类Complex ,它将从vectorSpace派生,将double指定为数据类型,定义sumdot 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM