C++-对基类运算符的未定义引用

C++ - undefined reference to Base class operator

本文关键字:未定义 引用 运算符 基类 C++-      更新时间:2023-10-16

我有一个模板基类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)'

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

我在这篇文章中读到,这可能是由于在声明派生类时基类的隐式实例化,因为基类的方法还没有定义。

你认为这就是问题所在吗?什么是一个不错的变通办法?

EDIT:忘记从子级添加operator[],现在添加(它没有像我的代码中那样引起任何错误)。

即使Vect<double>::operator[]永远不会被调用,在构造派生对象的过程中,基vtable也必须使用一段时间,并且在声明内容时,基vttable有一个指向未定义方法的指针。这应该通过在基方法的声明中添加"=0"(通常称为"纯虚拟")来解决。

更改为

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

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

请注意,由于它是一个模板类,因此不能在非头源文件中实现运算符。

既然我已经说了所有这些,让我也指出,如果你没有(正确地)遵循0、3或5的规则,你就会泄露内存;你不使用std::vector有什么原因吗?