C++ - 对 Base class 运算符的未定义引用

C++ - undefined reference to Base class operator

我有一个模板库 class Vect,VectDynamic 就是从中派生出来的。

基础 class (Vect.h):

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

派生 class (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) 创建派生 class 的实例时:

#include "VectDynamic.h"

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

    return 0;
}

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

现在我知道很多 post 都在谈论这种错误,但经过数小时的搜索,我找不到任何原因会在我的案例中发生。
我认为错误不会来自我包含文件的方式,因为当所有内容都在一个文件中时它也不起作用。

我在 this post 中读到这可能是由于基 class 的隐式实例化在派生 class 是因为基础 class 的方法尚未定义而声明。

你认为这是问题所在吗? 什么是合适的解决方法?

编辑:忘记添加 child 中的 operator[],现在添加它(它没有引起任何错误,因为它在我的代码)。

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

请注意,由于它是一个模板 class,您无法在 non-header 源文件中实现运算符。

既然我已经说了这么多,我还要指出,因为你没有(正确地)遵循 0、3 或 5 的规则,你将泄漏内存;您有没有使用 std::vector 的原因?

尽管 Vect<double>::operator[] 永远不会被调用,但在派生对象的构造过程中必须暂时使用基 vtable,并且在您声明事物时,基 vtable 有一个指向未定义方法的指针。这应该通过在基本方法的声明中添加“=0”(通常描述为 "pure virtual")来解决。

改为

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