C ++ - 对基类操作符

时间:2015-12-08 16:06:06

标签: c++ templates inheritance operator-overloading

我有一个模板基类Vect,从中派生VectDynamic。

基类(Vect.h):

template <typename Elem>
class Vect
{
public:
    virtual Elem& operator[](std::ptrdiff_t);
};

派生类(VectDynamic.h):

#include "Vect.h"

template <typename Elem>
class VectDynamic: public Vect<Elem>
{
    std::size_t _dim;
    Elem* _val;
public:
    explicit VectDynamic(std::size_t dim = 0): _dim(dim), _val(new Elem[dim]) {}
    VectDynamic(std::size_t, const Elem&);
    VectDynamic(const VectDynamic&); 
    Elem& operator[](std::ptrdiff_t) override;
};

template <typename Elem>
VectDynamic<Elem>::VectDynamic(std::size_t size, const Elem& e):
    _dim(size), _val(new Elem[size]) 
{
    for (std::size_t i = 0; i < size; ++i) _val[i] = e;
}

template <typename Elem>
VectDynamic<Elem>::VectDynamic(const VectDynamic& v): 
    _dim(v._dim), _val(new Elem[v._dim])
{
    for (std::size_t i = 0; i < v._dim; ++i) _val[i] = v._val[i];
}

template <typename Elem>
Elem& VectDynamic<Elem>::operator[] (std::ptrdiff_t i) 
{
    if (std::size_t(i) >= _dim)
        throw std::out_of_range("VectDynamic : Index out of range");
    return _val[i];
}

当我尝试像这样(main.cpp)创建派生类的实例时:

#include "VectDynamic.h"

int main()
{
    VectDynamic<double> v1(5, 2);

    return 0;
}

我最终从这两个类中得到了这个错误:
undefined reference to 'VectDynamic<double>::operator[](long)'

现在我知道很多帖子都在谈论这种错误,但经过几个小时的搜索,我无法找到任何理由在我的情况下发生这种情况。
我不认为错误会来自我包含文件的方式,因为当所有内容都在一个文件中时它不起作用。

我在this帖子中读到,这可能是由于基类的隐式实例化在声明派生类时发生的,因为基类的方法不是&# 39; t尚未定义。

你认为这是问题吗? 什么是一个体面的解决方法?

编辑:忘记添加来自孩子的operator[],现在添加它(它不会导致我的代码中出现任何错误)。

2 个答案:

答案 0 :(得分:0)

从错误中可以清楚地看出,你没有定义VectDynamic<double>::operator[]。如果您不希望[]运算符只删除函数声明。如果你确实需要它,你需要实现它。

请注意,由于它是模板类,因此无法在非标头源文件中实现运算符。

现在我已经说了所有这些,让我也指出,因为你没有(正确地)遵循0,3或5的规则你会泄漏记忆;您有没有使用std::vector的原因?

答案 1 :(得分:0)

即使永远不会调用Vect<double>::operator[],在构造派生对象期间必须使用基本vtable一段时间,并且在声明事物时,基本vtable具有指向该未定义方法的指针。这应该通过在基本方法的声明中添加“= 0”(通常描述为“纯虚拟”)来解决。

更改为

template <typename Elem>
class Vect
{
public:
    virtual Elem& operator[](std::ptrdiff_t)=0;
};