Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-对基类运算符的未定义引用_C++_Templates_Inheritance_Operator Overloading - Fatal编程技术网

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

C++ C++;-对基类运算符的未定义引用,c++,templates,inheritance,operator-overloading,C++,Templates,Inheritance,Operator Overloading,我有一个模板基类Vect,VectDynamic就是从中派生出来的 基类(向量h): 模板 类向量 { 公众: 虚拟电子和操作员[](标准::ptrdiff_t); }; 派生类(VectDynamic.h): #包括“Vect.h” 模板 类VectDynamic:公共Vect { 标准:尺寸; 元素*\u val; 公众: 显式向量动力学(std::size\t dim=0):\u dim(dim),\u val(new Elem[dim]){ 矢量动力学(标准:大小、常数和); 矢量动力

我有一个模板基类Vect,VectDynamic就是从中派生出来的

基类(向量h):

模板
类向量
{
公众:
虚拟电子和操作员[](标准::ptrdiff_t);
};
派生类(VectDynamic.h):

#包括“Vect.h”
模板
类VectDynamic:公共Vect
{
标准:尺寸;
元素*\u val;
公众:
显式向量动力学(std::size\t dim=0):\u dim(dim),\u val(new Elem[dim]){
矢量动力学(标准:大小、常数和);
矢量动力学(constvectdynamic&);
元素和运算符[](标准::ptrdiff_t)覆盖;
};
模板
VectDynamic::VectDynamic(标准::大小\u t大小,常量元素和e):
_尺寸(尺寸),_val(新元素[尺寸])
{
对于(std::size_t i=0;i
当我尝试创建如下派生类的实例(main.cpp)时:

#包括“VectDynamic.h”
int main()
{
矢量动力学v1(5,2);
返回0;
}
我最终在两个类中都出现了这个错误:
对“VectDynamic::operator[](long)的未定义引用

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

我在博文中读到,这可能是由于基类的方法尚未定义,所以在声明派生类时,基类的隐式实例化发生了

你认为这就是问题所在吗? 什么是体面的解决办法


编辑:忘记添加子项中的
运算符[]
,现在添加了它(它没有像我的代码中那样导致任何错误)。

从错误中可以清楚地看出,您只是没有定义
向量动力学::运算符[]
。如果不需要[]运算符,只需删除函数声明即可。如果您确实想要它,您需要实现它

注意,因为它是一个模板类,所以不能在非头源文件中实现操作符

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

即使永远不会调用
Vect::operator[]
,在构造派生对象的过程中,基本vtable必须使用一段时间,并且正如您声明的那样,基本vtable有一个指向该未定义方法的指针。这应该通过在基方法的声明中添加“=0”(通常称为“纯虚拟”)来解决

改为

template <typename Elem>
class Vect
{
public:
    virtual Elem& operator[](std::ptrdiff_t)=0;
};
模板
类向量
{
公众:
虚拟元素和运算符[](标准::ptrdiff_t)=0;
};

为什么在基类运算符声明上没有
=0
(因为您似乎不想定义它)?使
Vect
运算符[]
纯虚拟?谢谢你们,这已经解决了问题,尽管我不明白为什么问题没有出现得更快…我在答案中加入了您的评论,因此,我可以问心无愧地投票。你能详细说明一下,使基类纯化将如何改变有关子
运算符[]
定义的任何内容吗?@MarkB你注意到了吗?Bathsheba将我先前的评论复制到了我的答案中?使基函数为纯函数确实会更改派生函数,但会更改基vtable。派生构造函数使用基本构造函数,它使用基本vtable。原始错误来自基本vtable。使用基本vtable不会产生任何效果,并且可以被优化器删除。但是根据它的删除情况,它是不正确的。@JSF我已经读了大约五遍错误消息,据我所知,它说,对
VectDynamic::operator[](long)
,即子运算符函数体本身的未定义引用。这与可能存在的任何vtable问题都是正交的。@MarkB,对不起,您是对的。我看到了一个错误,但错过了更大的错误。我没有遵循代码中的3/5/0规则,因为我只复制了导致问题的部分。我没有特别的理由不使用
std::vector
,只是因为我使用的东西对我来说很好,所以我觉得没有必要找到其他东西
#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];
}
#include "VectDynamic.h"

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

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