使用C ++中的CRTP继承在基类中实现的方法

时间:2016-03-25 15:24:47

标签: c++ templates inheritance crtp

我对C ++中的模板不太熟悉,所以我很难解决以下问题。

我有班级Vector2DVector3D,但我希望他们从班级Vector继承。为了能够在Vector中定义常用函数,我正在使用CRTP(Curiously Recurring Template Pattern)。

这是我的Vector课程的短版本:

#pragma once

#include "../stdafx.h"

template <class VectorImpl>
class Vector {
public:
    VectorImpl& operator=(const VectorImpl& other);

    virtual const float operator*(const VectorImpl& other) const = 0;

    friend const VectorImpl operator*(const float& scalar, const VectorImpl& other);
    virtual VectorImpl& operator*=(const float& scalar) = 0;

    float abs() const;

    virtual std::string toString() const = 0;

    virtual ~Vector() = 0 {};

protected:
    virtual void copyFrom(const VectorImpl& other) = 0;
};

-----------------------------------------------------------------------------------------

#include "Vector.h"
#include "Vector2D.h" // edit
#include "Vector3D.h" // edit

template <class VectorImpl>
VectorImpl& Vector<VectorImpl>::operator=(const VectorImpl& other) {
    this->copyFrom(other);

    // edit
    // return *this;
    return static_cast<VectorImpl&>(*this);
}

template <class VectorImpl>
const VectorImpl operator*(const float& scalar, const VectorImpl& other) {
    VectorImpl result = other;
    result *= scalar;
    return result;
}

template <class VectorImpl>
float Vector<VectorImpl>::abs() const {
    const VectorImpl thisImpl = static_cast<const VectorImpl&>(*this); // edit
    return std::sqrt(thisImpl * thisImpl);
}

// edit
template class Vector<Vector2D>;
template class Vector<Vector3D>;

这是我的Vector2D课程的短版本:

#pragma once

#include "../stdafx.h"
#include "Vector.h"

class Vector2D :
    public Vector<Vector2D> {
public:
    Vector2D();
    Vector2D(const Vector2D& other);
    Vector2D(const float& xPos, const float& yPos);

    const float operator*(const Vector2D& other) const;

    Vector2D& operator*=(const float& scalar);

    std::string toString() const;

    ~Vector2D();

protected:
    void copyFrom(const Vector2D& other);

private:
    float xPos;
    float yPos;
};

-----------------------------------------------------------------------------------------

#include "Vector2D.h"

Vector2D::Vector2D() :
xPos(0.0f),
yPos(0.0f) {
}

Vector2D::Vector2D(const Vector2D& other) {
    this->copyFrom(other);
}

void Vector2D::copyFrom(const Vector2D& other) {
    if (this != &other) {
        this->xPos = other.getXPos();
        this->yPos = other.getYPos();
    }
}

Vector2D::Vector2D(const float& xPos, const float& yPos) {
    this->xPos = xPos;
    this->yPos = yPos;
}

const float Vector2D::operator*(const Vector2D& other) const {
    return this->xPos * other.getXPos() + this->yPos * other.getYPos();
}

Vector2D& Vector2D::operator*=(const float& scalar) {
    this->xPos *= scalar;
    this->yPos *= scalar;
    return *this;
}

std::string Vector2D::toString() const {
    std::string ret = std::to_string(this->xPos);
    ret += " ";
    ret += std::to_string(this->yPos);

    return ret;
}

Vector2D::~Vector2D() {
    // intentionally left blank
}

问题是,对于Vector2DVector3D分别执行的方法的每次调用,Vector中都会出现LNK2019错误(未解析的外部符号& #39;符号&#39;在函数&#39;函数&#39;中引用。 我很确定我的模板实现有些不对劲,但我无法弄清楚它是什么。我现在正在研究几个小时。

我感谢任何帮助,所以提前谢谢。

编辑:

我添加了模板类的必要实例化,但现在我得到了转换错误。添加

VectorImpl result = static_cast<const VectorImpl>(*this);

VectorImpl result = static_cast<VectorImpl>(*this);

不会改变问题。我在这里仍然缺少什么?

编辑2:

好吧当然有static_cast<const VectorImpl&>(*this)。 我还添加了这些演员阵容,但现在我再次得到该死的链接错误。这次只能链接函数friend operator*abs。我没有看到其他功能有太大差异。那他们为什么会有问题呢?

0 个答案:

没有答案